是否值得为一个方法编写测试,该方法调用其他方法,而这些方法 100% 被各个单元测试覆盖?
最近我一直在阅读 Roy Osherove 写的《单元测试的艺术》一书,我在想如何处理这样的情况:
假设我有一个大方法,通过完成不同的任务来根据传递的参数完成业务流程:
public void MonsterMehtod(Parameters p)
{
// Some processes to accomplish TASK_A
// ....
// Some processes to accomplish TASK_B
// ....
// Some processes to accomplish TASK_C
// ....
}
而我想要对此方法编写测试。
因此,如果我将这个大方法排除在像这样的较小方法中:
public void MonsterMethod(Parameters p)
{
Task_A(p);
Task_B(p); //Can behave different depending on Task_A(p) results
Task_C(p); //Can behave different depending on Task_A(p) and Task_B(p) results
}
并且我为每个任务编写单元测试,如下所示:
[Test]
public void Task_A_AllPossibleConditionsWithParameterP_ExpectedBehaviours() {}
[Test]
public void Task_B_AllPossibleConditions_ExpectedBehaviours()
{
// Tests all possible expected behaviours based on injected parameters
// Tests all possible expected behaviours based on method Task_A(Prameters p) results
}
[Test]
public void Task_C_AllPossibleConditions_ExpectedBehaviours()
{
// Tests all possible expected behaviours based on injected parameters
// Tests all possible expected behaviours based on method Task_A(Prameters p) results
// Tests all possible expected behaviours based on method Task_B(Prameters p) results
// Tests all possible expected behaviours based on method Task_C(Prameters p) results
}
那么,毕竟,为 MonsterMethod(Parameters p) 编写另一个测试是否有意义,例如:
[Test]
public void MonsterMehtod_AllPossibleParameterConditions_ExpectedBehaviours {}
也许我至少可以编写一个测试来检查是否调用了所有 Task_A()、Task_B()、Task_C() 方法,但是虽然我对每个子任务进行了所有单元测试,但是否值得进行另一个测试(也许应该调用它)包含所有这些子任务的 MonsterMethod(Parameters p) 的集成测试而不是单元测试?
Recently I have been reading The Art Of Unit Testing book by Roy Osherove and I was thinking how to deal with such a situation:
Assume that I have a big method that accomplishes a business process based on the passed parameters by completing different tasks:
public void MonsterMehtod(Parameters p)
{
// Some processes to accomplish TASK_A
// ....
// Some processes to accomplish TASK_B
// ....
// Some processes to accomplish TASK_C
// ....
}
And I want to write test(s) on this method.
So, if I exclude this big method to smaller methods like this:
public void MonsterMethod(Parameters p)
{
Task_A(p);
Task_B(p); //Can behave different depending on Task_A(p) results
Task_C(p); //Can behave different depending on Task_A(p) and Task_B(p) results
}
And I write unit tests for each task like this:
[Test]
public void Task_A_AllPossibleConditionsWithParameterP_ExpectedBehaviours() {}
[Test]
public void Task_B_AllPossibleConditions_ExpectedBehaviours()
{
// Tests all possible expected behaviours based on injected parameters
// Tests all possible expected behaviours based on method Task_A(Prameters p) results
}
[Test]
public void Task_C_AllPossibleConditions_ExpectedBehaviours()
{
// Tests all possible expected behaviours based on injected parameters
// Tests all possible expected behaviours based on method Task_A(Prameters p) results
// Tests all possible expected behaviours based on method Task_B(Prameters p) results
// Tests all possible expected behaviours based on method Task_C(Prameters p) results
}
So, after all, is it meaningful to write another test for MonsterMethod(Parameters p) like:
[Test]
public void MonsterMehtod_AllPossibleParameterConditions_ExpectedBehaviours {}
Maybe I can at least write a test to check if all Task_A(), Task_B(),Task_C() methods are called but while I have all the unit tests for each sub-task, is it worth having another test (maybe it should be called an integration test rather than a unit test) for MonsterMethod(Parameters p) that houses all those sub-tasks?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您编写一个方法,那么它的作用可能与您已有的任何其他方法不同。那么测试它是否正确地执行其他操作(是否正确地组合其他函数的结果)是有用的。
If your writing a method, than it presumably does something different than any other method you already have. It is useful then to test that it does that other thing (be it correctly composing the results of other functions) correctly.
您应该根据您期望的怪物方法处理子任务的方式来测试它。但这并不意味着您需要执行子任务。
我建议取消子方法,并单独测试怪物方法。
这可以通过将每个任务方法虚拟化并使用模拟框架来消除子方法,或者只是自己手动执行来轻松完成。
You should test the monster method with how you expect it to handle the child tasks. That does not mean, however, that you need to execute the child tasks.
I would suggest stubbing out the child methods, and testing the monster method in isolation.
This can easily be done by making each Task method virtual and using a mocking framework to stub out the child methods, or just manually doing it yourself.
我想说这是值得的。如果您最终删除了一些内部任务,那么您的 Monster 方法仍将受到测试。
I would say it's worth it. If you end up removing some the inner tasks then your Monster method will still be tested.