Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.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/jsf-2/2.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 Mockito mock所有方法调用并返回_Java_Unit Testing_Junit_Mockito - Fatal编程技术网

Java Mockito mock所有方法调用并返回

Java Mockito mock所有方法调用并返回,java,unit-testing,junit,mockito,Java,Unit Testing,Junit,Mockito,我在用mock编写单元测试时遇到了一个问题。有一个我需要模拟的对象有很多getter,我在代码中调用它们。然而,这些并不是我单元测试的目的。那么,有没有一种方法可以让我模仿所有的方法,而不是一个一个地模仿它们 下面是代码示例: public class ObjectNeedToMock{ private String field1; ... private String field20; private int theImportantInt; public String getFiel

我在用mock编写单元测试时遇到了一个问题。有一个我需要模拟的对象有很多getter,我在代码中调用它们。然而,这些并不是我单元测试的目的。那么,有没有一种方法可以让我模仿所有的方法,而不是一个一个地模仿它们

下面是代码示例:

public class ObjectNeedToMock{

private String field1;
...
private String field20;

private int theImportantInt;


public String getField1(){return this.field1;}
...

public String getField20(){return this.field20;}

public int getTheImportantInt(){return this.theImportantInt;}

}
这是我需要测试的服务类

public class Service{

public void methodNeedToTest(ObjectNeedToMock objectNeedToMock){
    String stringThatIdontCare1 = objectNeedToMock.getField1();
    ...
    String stringThatIdontCare20 = objectNeedToMock.getField20();
    // do something with the field1 to field20

    int veryImportantInt = objectNeedToMock.getTheImportantInt();
    // do something with the veryImportantInt

    }
}
在测试类中,测试方法如下

@Test
public void testMethodNeedToTest() throws Exception {
      ObjectNeedToMock o = mock(ObjectNeedToMock.class);
      when(o.getField1()).thenReturn(anyString());
      ....
      when(o.getField20()).thenReturn(anyString());

      when(o.getTheImportantInt()).thenReturn("1"); //This "1" is the only thing I care

}

那么,有没有一种方法可以避免将无用的“field1”的所有“when”写入“field20”

您可以控制模拟的默认答案。创建模拟时,请使用:

Mockito.mock(ObjectNeedToMock.class, new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        /* 
           Put your default answer logic here.
           It should be based on type of arguments you consume and the type of arguments you return.
           i.e.
        */
        if (String.class.equals(invocation.getMethod().getReturnType())) {
            return "This is my default answer for all methods that returns string";
        } else {
            return RETURNS_DEFAULTS.answer(invocation);
        }
    }
}));

如果您对特定测试用例中
getField1()
getField20()
的结果不感兴趣,那么您根本不应该模拟它。换句话说,如果所有特定测试用例都应该关注的是
gettheimportant()
,那么您的测试用例应该如下所示:

@Test
public void testMethodNeedToTest() throws Exception {
      ObjectNeedToMock o = mock(ObjectNeedToMock.class);
      when(o.getTheImportantInt()).thenReturn("1");

      // test code goes here
}
对于kotlin用户:

val mocked:MyClassToMock = Mockito.mock(MyClassToMock::class.java,
                object:Answer<Any> {

            override fun answer(invocation: InvocationOnMock?): Any {
                    if (String::class.java.equals (invocation?.method?.getReturnType())) {
                        return "Default answer for all methods that returns string";
                    } else {
                        return Mockito.RETURNS_DEFAULTS.answer(invocation);
                    }
            }
        })
val mocked:MyClassToMock=Mockito.mock(MyClassToMock::class.java,
对象:答案{
覆盖有趣的答案(调用:invocationMock?):有吗{
if(字符串::class.java.equals(调用?.method?.getReturnType()){
return“返回字符串的所有方法的默认答案”;
}否则{
返回Mockito.RETURNS\u DEFAULTS.answer(调用);
}
}
})

如果可以将它们返回null,则不必这样做。我确实需要在方法中使用它们,很抱歉没有将其放在示例中。我已修改了我的示例,我确实需要对字段1到字段20执行一些操作,但这在测试方法中并不重要。嗯,这取决于具体情况。如果您对field1到field20所做的操作会影响您在测试中检查的结果,那么您别无选择,只能模拟这些值。否则,您仍然可以忽略它们,毕竟,您对测试感兴趣的所有内容都不会受到它的影响。另一方面,如果您有一个具有20个吸气剂的类,您应该真正考虑改进您的设计(即使它是实体类,它可能值得重新设计DB表以包含更少的列,因为SQL DBS中的长行在大多数DBS中显著地损害了性能)。。我感到很幸运,这个20 getters对象是来自第三方restful api调用的json响应映射类:-)正如我前面提到的,除了模拟整个过程之外,您没有其他选择。如果您并不真正关心这些值,那么可以采用另一个答案中的方法并定义默认值。如果您这样做了,那么最好使用一个helper方法,该方法将创建一个mock,并使用您作为helper方法的参数提供的值来存根它的每个方法。换句话说,当行代码时,您将使用20个参数对helper方法进行单个方法调用,而不是20个
。不确定我是否正确理解您的答案。我仍然需要在应答方法中手动将field1的默认值设置为field20?@jasonfungsing否您不需要。在本例中,您正在设置模拟对象的默认行为。事实上,如果调用
doReturn(…).when()
,您将使用新的自定义存根覆盖此默认行为。因此,如果您需要更改一个方法的行为,而其他方法仍将返回默认值,那么它非常有用。顺便说一句,我已经更新了我的答案。你也可以只做
mock(ObjectNeedToMock.class,返回默认值)不需要lambda。