blog/_posts/2018-02-22-how-to-reset-a-m...

2.1 KiB

title date layout category image description
How to reset a mocked object during test ? - Python 2018-02-22 post Programming /img/blog/how-to-reset-a-mocked-object-during-test-python.png Unittest appears to be such a pain to work with... Let's see if we can figure something out !

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 :

    {% highlight python %} p = patch("module.object", new=MagicMock(return_value="Blah")) p.start()

    self.assertTrue(methodToTest())

    p.stop()

    self.assertFalse(methodToTest()) {% endhighlight %}

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

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 :