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

49 lines
2.1 KiB
Markdown

---
title: "How to reset a mocked object during test ? - Python"
date: 2018-02-22
layout: post
category: Programming
image: /img/blog/how-to-reset-a-mocked-object-during-test-python.png
description: "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](/img/blog/how-to-reset-a-mocked-object-during-test-python.png)](/img/blog/how-to-reset-a-mocked-object-during-test-python.png)
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](https://stackoverflow.com/questions/15751467/unittest-python-mock-only-one-function-multiple-call/15752019#15752019), 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 :
<script src="https://gist.github.com/HorlogeSkynet/6f41e58fa30fe3da90f9804ab5983d5e.js"></script>