我有一个看起来像这样的方法:
def foo(self):
if not self.started:
self.start()
return None
# do some other stuff...
self.bar()
return self.baz()
我正在编写一个名为test_foo_calls_start_if_not_already_started_and_then_returns_immediately
的测试。
测试我们是否轻松调用start
:
with mock.patch.object(Thing, 'start') as mock_start:
thing = Thing()
thing.foo()
self.assertTrue(mock_start.called)
但是我怎么测试函数然后直接返回?我想我可以嘲笑酒吧和巴兹,并检查他们是不是被召唤,但这将是一个难以维持。
答案 0 :(得分:1)
很难知道没有看到更多代码,但我会说一种技术是使用self
上的下一个函数调用并断言未调用。如果没有,只有在没有开始的情况下才返回,那么你就有很强的意义。
假设self.bar()
是即时通话,修补bar
,然后检查它是否被调用,就像...一样简单...
assert not mock_start.calls
然而,我喜欢非常短的单元测试,并且修补方法(如果不使用某种依赖注入),而不是使用上下文管理器。部分模拟的对象无论如何都要立即丢弃,所以这样做是安全的。像这样:
def test1(self):
thing = Thing()
thing.started = False # Maybe it would make sense to include this
thing.start = Mock()
thing.bar = Mock()
res = thing.foo()
assert res is None
assert thing.start.called
assert not thing.bar.called
模拟框架可以简化测试活动,但最终可测试性归结为您的代码及其质量。一般提示是:返回有意义的值,将代码重新分解为更小的方法,允许更精确地检查调用,改变状态或返回值,但不是两者,等等。