例如:
public class NumberService {
public boolean isNaturalNumber(int num) {
return num > 0;
}
public String getClassificationInfo(int num) {
return isNaturalNumber(num) ? num + "is a natural number" : num + "is not a natural number";
}
}
这里有两个公共方法,而方法getClassificationInfo
称为方法isNaturalNumber
。
在测试isNaturalNumber
时模拟getClassificationInfo
是一个好习惯吗?
赞:
@RunWith(MockitoJUnitRunner.class)
public class NumberServiceTest {
@Spy
private NumberService numberService;
@Test
public void test_getClassificationInfo_when_is_natural_number() {
int num = generateInt();
doReturn(true).when(numberService).isNaturalNumber(num);
String classificationInfo = numberService.getClassificationInfo(num);
assertThat(classificationInfo).isEqualTo(num + "is a natural number");
}
@Test
public void test_getClassificationInfo_when_is_not_natural_number() {
int num = generateInt();
doReturn(false).when(numberService).isNaturalNumber(num);
String classificationInfo = numberService.getClassificationInfo(num);
assertThat(classificationInfo).isEqualTo(num + "is not a natural number");
}
// the other test for isNaturalNumber
private int generateInt() {
return new Random().nextInt();
}
}
答案 0 :(得分:1)
在这种特殊情况下,模拟调用的方法没有任何意义。但是,这不仅仅是因为它是同一类的方法。实际上,有时会专门引入相同类的方法来模拟它们。例如,如果在您的类中处理通过文件I / O获得的某些数据,则可以将文件I / O隔离到其自身的方法中。然后,您可以使用模拟版本的文件I / O方法来测试数据处理。
但是,在这种情况下,没有充分的理由在isNaturalNumber
的测试中模拟getClassificationInfo
:方法isNaturalNumber
具有确定性的行为,不会导致执行时间过长。通过模拟isNaturalNumber
在getClassificationInfo
的一项测试中有意表现为错误的情况,您似乎不太可能获得很多收益。
您不必教条地嘲笑一切。例如,您也不模拟sin
或cos
之类的标准库数学函数,因为它们在大多数情况下也不会引起问题。模拟是有原因的。因此,如果您考虑模拟函数或方法,则应该知道要解决的问题。如果没有问题要解决,请不要嘲笑。
答案 1 :(得分:0)
否这不是一个好习惯,因为我们应该在涉及其他模块/类对象的地方模拟存根。
例如:
Transformation
然后,您应该模拟B的someMethod(),而不应该模拟A的someLogic(),因为您正在对A的aDoingSomeBWork()方法进行单元测试。如果您模拟someLogic();在单元测试中,则可能会发生代码中断的情况。