具有两个模拟对象的Python单元测试,如何验证调用顺序? [英] Python Unit Testing with two mock objects, how to verify call-order?

查看:94
本文介绍了具有两个模拟对象的Python单元测试,如何验证调用顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个类,该类编排了两种仪器(一个可远程控制的电源单元和一个用于控制被测设备的总线控制器),以便在被测设备上执行各种测量( DUT).

I'm writing a class that orchestrates two instruments (a remote controllable power supply unit and a bus controller used to control the Device-Under-Test) in order to perform all kinds of measurements on a Device-Under-Test (DUT).

对这两种工具的访问均作为Python类实现,并且对每个类的引用都可用于新类. DUT有点精致,具有非常特殊的加电顺序,涉及到对电源和总线控制器的调用,并且必须按照特定的顺序进行,以免损坏DUT.

Access to both instruments is implemented as Python classes and a reference to each is available to the new class. The DUT is somewhat delicate and has a very specific power-up sequence involving calls to the power supply and bus controller and has to happen in that specific order to avoid damaging the DUT.

现在,我想为此课程编写一个单元测试.我目前正在为此使用鼻子测试和模拟包.因此,我的想法是模拟两个乐器类并验证这些乐器类的正确调用顺序.

Now I want to write a unit-test for this class. I am currently using nosetests and the mock-package for this. So my idea was to mock both instrument classes and verify the correct call order for those.

验证每个模拟类本身的调用顺序似乎非常容易.因此,我能够找出电源是否已订购,以便先正确施加电池电压,然后再施加数字域电压,然后再施加模拟域电压.我还发现数字寄存器已被编程为正确的值.但是,我一直无法确定在写入数字域电压和模拟域电压之间是否发生了写数字寄存器的调用.

It seems to be very easy to verify the call order for each mocked class itself. Hence, I am able to find out if the power supply was ordered to correctly apply battery voltage first, then digital domain voltage and then analog domain voltage. I can also find out that the digital registers have been programmed to the correct values. However, I'm stuck determining if the call to write the digital registers happened between applying the digital domain voltage and analog domain voltage.

所以我的问题是:如果我有两个模拟对象,如何验证这些对象之间的特定调用顺序?我的第一个操作虽然是检查呼叫的时间戳,但似乎不存在.

So my question is: If I have two mocked objects, how can I verify a specific order of calls between those objects? My first though was to check timestamps of the calls but those don't seem to exist.

推荐答案

您可以做的是将您的模拟对象放到新的Mock()对象中,并检查新模拟对象的模拟调用.也许一个例子更容易理解:

What you can do is put your mocks in a new Mock() object and check the mock's calls of the new mock. Maybe an example is simpler 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()]

好的,我们现在处于良好状态:我们可以检查m的调用以验证正确的顺序:

Ok now we are in good position: we can just check the calls of m to verify 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 inverse order fail.

使用patch时,只需将补丁返回的模拟文件放入容器中,并将其放入新的Mock()中.在记录子电话订单的容器上进行检查.

When you use patch simply take the mocks returned by the patches and put them in a new Mock() as container. Do your check on the container that record the child calls order.

这篇关于具有两个模拟对象的Python单元测试,如何验证调用顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆