Python Unit Testing with two mock objects, how to check call order?

I am writing a class that organizes two instruments (a remote controlled power supply and a bus controller used to control device testing) in order to perform all kinds of measurements on a device under control (DUT).

Access to both tools is implemented as Python classes, and a link to them is available for the new class. The DUT is somewhat delicate and has a very specific power-on sequence, including calls to the power controller and bus, and must occur in this particular order to avoid damage to the device under test.

Now I want to write unit-test for this class. I am currently using nosetests and mock-package for this. So my idea was to make fun of both tool classes and check the correct call order for them.

It seems very easy to check the call order for each of the mocked class. Therefore, I can find out if it was correct to charge the battery voltage when ordering power, then the digital domain voltage, and then the analog domain voltage. I can also find out that the digital registers are programmed to the correct values. However, I was stuck in determining whether there was a call to write digital registers between applying digital domain voltage and analog voltage in a domain.

So my question is: if I have two mocking objects, how can I check the specific order of calls between these objects? My first though was to check the timestamps of calls, but they don't seem to exist.

+7
python unit-testing order mocking
source share
1 answer

What you can do is put your mocks in a new Mock() object and check the layout of the calls of the new layout. Maybe an example is easier to understand:

 >>> from unittest.mock import * >>> m0, m1 = Mock(), Mock() >>> m = Mock() >>> m.m0, m.m1 = m0, m1 >>> m0() <Mock name='mock.m0()' id='140660445334224'> >>> m1() <Mock name='mock.m1()' id='140660445334608'> >>> m.mock_calls [call.m0(), call.m1()] 

Ok, now we are in a good position: we can just check the calls to m to check the correct order:

 >>> m.assert_has_calls([call.m0(), call.m1()]) >>> m.assert_has_calls([call.m1(), call.m0()]) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/local/lib/python2.7/dist-packages/mock.py", line 863, in assert_has_calls 'Actual: %r' % (calls, self.mock_calls) AssertionError: Calls not found. Expected: [call.m1(), call.m0()] Actual: [call.m0(), call.m1()] 

As we want, the first pass and the reverse order will not pass.

When you use patch , just take the layouts returned by the patches and put them in the new Mock() container. Make your check on a container that records orders for calls from children.

+9
source share

All Articles