I don’t know if this post title is good enough, but that is something I was facing some days ago :

A missing blog post image

The problem here can be described as below :

  • We’d like to mock the first (or the last ?) Popen call, to test the chained external calls logic

  • We can’t mock totally Popen, because each call would return the same thing, and this is not what we want here

  • There is exactly the same problem with check_output calls (the first one has to fail, whereas the second one should have its “default” behavior)

  • These calls happen during the same tested method, so it’s not possible to reset the mock like some persons use to do :

    p = patch("module.object", new=MagicMock(return_value="Blah"))
    p.start()

    self.assertTrue(methodToTest())

    p.stop()

    self.assertFalse(methodToTest())
    

So I’ve tried something, based upon this StackOverflow thread, and the result was impressive after some struggles, as expected :smirk:

The idea is :

  • Mock the object you want to mock with a new object you control

  • This new object will behave in function of an internal state that you set

  • Decide when you want to mock this object with a “patched” entity, or let it act with its default behavior !

So let’s stop endless sentences and present a working solution please !

Yeah, you’ll find below a simple use case to illustrate this principle :