在同一个类中模拟其他公共方法是一种好习惯

问题描述 投票:0回答:2

例如:

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();
}
}
java unit-testing mocking
2个回答
1
投票

在这种特殊情况下,模拟调用的方法没有意义。然而,这不仅仅是因为它是同一类的方法。实际上,有时会引入同一类的方法以允许它们被模拟。例如,如果在您的类中处理通过文件I / O获得的某些数据,则可以将文件I / O隔离到自己的方法中。然后,您可以使用模拟版本的文件I / O方法测试数据处理。

然而,在这种情况下,没有充分的理由在isNaturalNumber的测试中模拟getClassificationInfo:方法isNaturalNumber具有确定性行为并且不会导致不可接受的长执行时间。通过模拟isNaturalNumber故意在getClassificationInfo的一个测试中表现错误的情况,你似乎也不太可能获得更多。

你不必粗暴地模仿一切。例如,您也不会模拟标准库数学函数,如sincos,因为它们在大多数情况下也不会导致问题。嘲笑应该是有原因的。因此,如果您考虑模拟函数或方法,您应该知道要解决的问题。如果没有问题要解决,请不要嘲笑。


0
投票

不是它不是很好的做法,因为我们应该模拟其他模块/类对象所涉及的存根。

例如:

public class A{
   private B aObj;

   public void aDoingSomeBWork(){
      aObj.someMethod();
      someLogic();
  }
   private/public/any modifier void someLogic(){
     //some logic
   }
}

public class B{
   public void someMethod(){}
}

然后你应该模拟B的someMethod(),但不应该是A的someLogic(),因为你是单元测试A的aDoingSomeBWork()方法。如果你模拟someLogic();在单元测试中,可能存在代码中断的情况。

© www.soinside.com 2019 - 2024. All rights reserved.