python - 单元测试、断言函数 Called() 和代码灵活性

标签 python unit-testing mocking integration-testing

这是一个关于单元测试以及是否/在哪里划定测试内容界限的问题

假设有一个这样的函数:

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,因为它

  • 是否强制执行如何完成额外工作的特定实现,因此它不会破坏 future 的重构,例如提高速度但具有不同的调用签名。相反,只有当 do_additional_work() 应该修改/提供的状态错误时,它才会中断。

  • 如果你做A,你会在哪里划清界限?您是否还需要模拟断言 do_work() 被调用一次?

<小时/>

但是,如果 function() 有自己的逻辑,您可以对其进行参数化,例如:

def function(conditional):
    do_work() if(conditional) else do_different_work()

然后我就会看到编写单元测试来模拟断言两个不同分支的理由。

<小时/>

您会编写哪些测试? (A)、(B) 或两者

最佳答案

一般来说,倾向于让测试松散耦合,因为这样可以使它们不那么脆弱。异常(exception)情况是,调用 do_work 是重要行为,而不仅仅是调用它所导致的状态更改。这可能是在将被子类覆盖的方法中的情况。

也就是说,测试的目的是让你的工作变得更容易(尤其是在维护方面),有时仅仅为了满足上述要求而重构代码是不切实际的(例如,当你向遗留代码添加测试以进行更改之前记录行为)。在这种情况下,请在测试的评论中解释您的推理,然后继续。

关于python - 单元测试、断言函数 Called() 和代码灵活性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42938377/

相关文章:

c# - 使用 Moq 和 xUnit 模拟和测试 LogError 消息

python - pandas read_csv 将列转换为 int 类型

python - 支持回推的迭代器

c# - NSubstitute Received(count) 始终为绿色(模拟具体类时)

java - 从 Java 到 Coldfusion 的多部分文件传输 - 无前导边界 : %PDF-1. 4

android - 分享CoroutineExecutorExtension的定义

python - Lambda 上的 MySQL 连接器产生无法导入模块 'myapp' : No module named 'mysql'

python - 如何避免 Django 的分页器的 COUNT 查询呢?

java - 在不继承抽象类的情况下模拟对抽象类的公共(public)方法的调用,最好使用 mockito

python - 如何修补 `pathlib.Path.exists()` 方法?