最近我一直在阅读Roy Osherove撰写的The Art Of Unit Testing一书,我正在考虑如何应对这种情况:
假设我有一个很大的方法,通过完成不同的任务,根据传递的参数完成业务流程:
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(参数p)编写另一个测试是否有意义,如:
[Test]
public void MonsterMehtod_AllPossibleParameterConditions_ExpectedBehaviours {}
也许我至少可以编写一个测试来检查是否所有的Task_A(),Task_B(),Task_C()方法都被称为,但是当我对每个子任务进行了所有单元测试时,是否值得拥有另一个测试(也许它应该被称为集成测试,而不是单元测试),MonsterMethod(参数p)包含所有这些子任务?
答案 0 :(得分:4)
如果你写一个方法,那么它可能与你已经拥有的任何其他方法有所不同。然后测试它是否正确地执行了其他事情(正确地组成其他函数的结果)是有用的。
答案 1 :(得分:3)
你应该用你期望它处理子任务的方式来测试怪物方法。但是,这并不意味着您需要执行子任务。
我建议删除子方法,并单独测试怪物方法。
这可以通过使每个Task方法虚拟化并使用模拟框架来存根子方法,或者只是自己手动完成来轻松完成。
答案 2 :(得分:1)
我会说这是值得的。如果你最终删除了一些内部任务,那么你的Monster方法仍然会被测试。