假设有这样的函数:
def function():
do_work()
您必须修改您遇到的问题,如下所示:
def function():
do_work()
do_additional_work()
你应该(A)为function()
添加一个如下所示的单位测试:
def test_function_called_additional_work():
mocked_additional_work = mock(function.do_additional_work)
function()
assert mocked_additional_work.called_once
或者你应该(B)编写一个依赖于function()
的集成测试:
def test_additional_work_was_done_upon_function_call():
assert some_client.state == add_work_was_not_done
function()
assert some_client.state == add_work_was_done
或者你应该写两个?
我的第一个镜头是不做 A 而更喜欢 B ,因为它
不强制执行额外工作的具体实现,因此它不会在未来的重构中破坏,例如提高速度,但有一个不同的呼叫签名。相反,只有当do_additional_work()
应修改/提供的状态错误时才会中断。
如果你做 A 你在哪里画线?您是否还需要模拟断言do_work()
被调用一次?
但是,如果function()
具有自己的逻辑,那么您可以进行参数化,例如:
def function(conditional):
do_work() if(conditional) else do_different_work()
然后我会看到编写单元测试的理由,这些单元测试会模拟断言两个不同的分支。
答案 0 :(得分:1)
一般来说,倾向于让测试松散耦合,因为它会使它们不那么脆弱。调用do_work
是重要行为时会出现异常,而不仅仅是调用它所导致的状态更改。在一个将被子类覆盖的方法中可能就是这种情况。
也就是说,测试可以使您的工作更轻松(特别是在维护方面),有时为了满足上述要求而重构代码是不切实际的(例如,当您将测试添加到遗留代码时进行更改前的文档行为)。在这种情况下,请在测试中的注释中解释您的推理并继续。