Course outline · 0% complete

0/29 lessons0%

Course overview →

Mocks: Asserting on Interactions

lesson 5-3 · ~11 min · 15/29

When the output IS the call

Some functions do not return interesting values, their whole job is a side effect: send the email, charge the card, write the log line. Stubbing cannot test that, because nothing comes back to assert on. You need a double that records what happened to it.

Python ships one in the standard library: unittest.mock.Mock. A Mock object accepts any call, remembers every call, and offers assertion helpers:

  • m.assert_called_once_with(args) fails unless m was called exactly once with those arguments
  • m.call_count tells you how many times it was called
  • Mock(return_value=x) makes it double as a stub that returns x

Same injection trick as lesson 5-2, but now the double is the thing you assert on after the act phase.

Code exercise · python

Run this. notify_user's job is to send a formatted message. The Mock stands in for the email sender, and afterward the test asserts the interaction: called once, with exactly the right arguments.

Quiz

assert_called_once_with would catch which bug that a plain stub could never see?

Code exercise · python

Your turn. checkout looks up a price and charges the card. Build get_price as a Mock with return_value 19.99, and charge as a plain Mock. After calling checkout, assert charge was called once with ("ada", 39.98), then print: interaction verified

Problem

One word: which kind of test double is an in-memory dictionary standing in for a real database, working for real but skipping the heavy machinery?