Hi Stuart,

> To reset, you just iterate over sys.modules and reset everything that is
a MagicMock (or anything with a reset_mock() method). There is no need to
figure which to reset, since you want all of them reset every test to
preserve test isolation. I haven't actually tried this bit yet.

Unfortunately, reset_mock doesn't reset as much as one would like it to.

It resets the call attributes on the mock, but it won't reset side_effects
and return_values. So if you rely on something like the options object in
the base layer being replaced by a MagicMock in most of your tests, but you
replace it with a fixture with some actual values in one of your tests, you
run into trouble pretty quickly. :-(

~ PeteVG

On Fri, Sep 9, 2016 at 8:53 PM Stuart Bishop <stuart.bis...@canonical.com>
wrote:

> On 9 September 2016 at 01:03, Pete Vander Giessen <
> pete.vandergies...@canonical.com> wrote:
>
>> Hi All,
>>
>> > Stuart Bishop wrote:
>> > The tearDown method could reset the mock easily enough.
>>
>> If only it were that simple :-)
>>
>> To patch imports, the harness was actually providing a context that you
>> could use the wrap the imports at the top of your test module. That solved
>> the immediate issue of executing imports without errors, but it created a
>> very complex situation when you went to figure out which references to
>> cleanup or update when you wanted to reset mocks. You also weren't able to
>> clean them up in tearDown, or even tearDownClass, because you had to handle
>> the situation where you had multiple test classes in a module.
>>
>> One workaround is to do your imports inside of the setUp for a test. That
>> didn't feel like the correct way to do things in a library meant for
>> general use, where I'd prefer to stick to things that don't make Guido sad.
>> I wouldn't necessarily object to the technique if it came up in a code
>> review for a specific charm, though :-)
>>
>
> I'm thinking you insert a MagicMock into sys.modules instead of an import
> statement (this is how we do it in the telegraf charm, and I'm sure helpers
> could make this nicer):
>
> # Mock layer modules
> import charms
> promreg = MagicMock()
> charms.promreg = promreg
> sys.modules['charms.promreg'] = promreg
>
> To reset, you just iterate over sys.modules and reset everything that is a
> MagicMock (or anything with a reset_mock() method). There is no need to
> figure which to reset, since you want all of them reset every test to
> preserve test isolation. I haven't actually tried this bit yet.
>
> If you are using the standard Python unittest feature set, I think you
> would need a TestCase subclass to do the reset. If you are using py.test, I
> think it has features that can do this magically.
>
> A moduleTearDown would be required if you want to remove the mocks from
> sys.modules (or py.test magic). But I don't think we need to bother.
>
>
>
> --
> Stuart Bishop <stuart.bis...@canonical.com>
>
-- 
Juju mailing list
Juju@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/juju

Reply via email to