有没有一种方法可以使Mock()返回有关调用参数的不同对象?

时间:2019-11-15 07:15:57

标签: python unit-testing mocking

我有要测试的代码(简化):

def foo(job):
    stop1 = job.stops.get(stop_number=1)
    stop1.departed_at = first_scan['scan_date']
    stop2 = job.stops.get(stop_number=2)
    stop2.pod_time = pod['received_date']

所以我这样做:

    job = Mock()
    foo(job)
    self.assertIsInstance(job.sync_at, datetime.datetime)
    self.assertAlmostEqual(job.booked_at, isoformat('2019-10-01T00:00:00'))
    self.assertAlmostEqual(job.stops.get(stop_number=1).departed_at, isoformat('2019-10-07T05:24:47'))
    self.assertAlmostEqual(job.stops.get(stop_number=2).pod_time, isoformat('2019-10-07T12:00:00'))

问题在于job.stops.get方法返回带有任何参数值的相同对象:

>>> job.stops.get(stop_number=1)
<Mock name='mock.stops.get()' id='140194394261936'>
>>> job.stops.get(stop_number=2)
<Mock name='mock.stops.get()' id='140194394261936'>
>>> 

因此,在测试上述代码时,我同时job.stops.get(stop_number=1)job.stops.get(stop_number=2)返回了设置了departed_atpod_time属性的相同输出。因此,我不确定pod_time是否设置为stop2而不是stop1,反之亦然。

问题是如何使mock返回与stop_number值有关的不同实例?

1 个答案:

答案 0 :(得分:0)

您可以将可调用对象分配给Mock对象的side_effect属性。根据不同的输入参数使可调用函数返回不同的对象:

def mock_get(stop_number):
    return {
        1: Mock(departed_at='2019-10-07T05:24:47'),
        2: Mock(pod_time='2019-10-07T12:00:00')
    }[stop_number]

job = Mock()
job.stops.get.side_effect = mock_get
foo(job)
assert job.stops.get(stop_number=1).departed_at == '2019-10-07T05:24:47' # passes
assert job.stops.get(stop_number=2).pod_time == '2019-10-07T12:00:00' # passes