Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在同一个类中模拟其他公共方法是一种好的做法吗_Java_Unit Testing_Mocking - Fatal编程技术网

Java 在同一个类中模拟其他公共方法是一种好的做法吗

Java 在同一个类中模拟其他公共方法是一种好的做法吗,java,unit-testing,mocking,Java,Unit Testing,Mocking,例如: 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"; } }

例如:

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

在测试
getClassificationInfo
时模拟
isNaturalNumber
是否是一种好的做法

像这样:

    @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();
}
}

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

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


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

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

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


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

不,这不是一个好的做法,因为我们应该在涉及其他模块/类对象的地方模拟存根

例如:


然后,您应该模拟B的someMethod(),而不应该模拟A的someLogic(),因为您正在单元测试A的AdoningSomebWork()方法。如果你嘲笑某个逻辑();在单元测试中,可能会出现代码中断的情况。

不,这不是一个好的做法,因为我们应该在涉及其他模块/类对象的地方模拟存根

例如:


然后,您应该模拟B的someMethod(),而不应该模拟A的someLogic(),因为您正在单元测试A的AdoningSomebWork()方法。如果你嘲笑某个逻辑();在单元测试中,可能会出现代码中断的情况。

您不需要使用间谍。如果您正在测试
NumberService
,那么它应该是真正的类。在您的示例中,
getClassificationInfo()
的实现取决于
isNaturalNumber()
的实现。如果你得到了错误的模拟,你的测试可能会通过,但实际上实现可能仍然是错误的。你不应该模拟类本身,而应该创建该类的对象并测试结果。。。只有在类中有依赖项时,模拟才会出现。。例如,如果您在
NumberService
上有其他服务,那么您可能会模拟该服务并将那些模拟的内容存根为空,除非您的测试变得缓慢-然后模拟依赖关系使测试变得缓慢(访问外部资源,如数据库、Web服务、文件系统等),除非准备测试变得非常复杂,否则您将使用复杂的配置模拟依赖项。我的问题是:
isNaturalNumber()
是否被其他代码使用?它真的需要公开吗?如果不是,那么它只是一个应该被显式测试的实现细节。@TimothyTruckle是的,isNaturalNumber被其他类使用,您不需要使用间谍。如果您正在测试
NumberService
,那么它应该是真正的类。在您的示例中,
getClassificationInfo()
的实现取决于
isNaturalNumber()
的实现。如果你得到了错误的模拟,你的测试可能会通过,但实际上实现可能仍然是错误的。你不应该模拟类本身,而应该创建该类的对象并测试结果。。。只有在类中有依赖项时,模拟才会出现。。例如,如果您在
NumberService
上有其他服务,那么您可能会模拟该服务并将那些模拟的内容存根为空,除非您的测试变得缓慢-然后模拟依赖关系使测试变得缓慢(访问外部资源,如数据库、Web服务、文件系统等),除非准备测试变得非常复杂,否则您将使用复杂的配置模拟依赖项。我的问题是:
isNaturalNumber()
是否被其他代码使用?这真的很有趣吗
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(){}
}