java Mockito 模拟所有方法调用和返回

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26154657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 09:23:24  来源:igfitidea点击:

Mockito mock all methods call and return

javaunit-testingjunitmockito

提问by jasonfungsing

I have a problem when writing unit testing with mock. There is a object which I need to mock have a lot getter, which I do call them at the code. However, those are not the purpose of my unit test. So, is there is a way I can mock all the methods instead of mock them one by one.

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

Here is the code example:

这是代码示例:

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;}

}

and this is the service class I need to test

这是我需要测试的服务类

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

    }
}

within the test class, the test method is like

在测试类中,测试方法就像

@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

}

So, is there a way that I can avoid writing all the "when" for the useless "field1" to "field20"

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

回答by SimY4

You can control the default answers of your mock. When you're creating the mock, use:

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

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

回答by ethanfar

If you're not interested in the result of getField1()to getField20()in a particular test case, you shouldn't mock it at all. In other words, if all the specific test case should be concerned about is getTheImportantInt(), then your test case should look like this:

如果您对特定测试用例中getField1()to的结果不感兴趣,则getField20()根本不应该嘲笑它。换句话说,如果所有特定的测试用例都应该关注的是getTheImportantInt(),那么你的测试用例应该是这样的:

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

      // test code goes here
}

回答by htafoya

For kotlin users:

对于 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);
                    }
            }
        })