Java 使用 Mockito 在另一个类中模拟一个类方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31596913/
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-08-11 11:17:51  来源:igfitidea点击:

Using Mockito to mock a class method inside another class

javaunit-testingjunitmockingmockito

提问by Chang Liu

I'm trying to write unit tests with Mockito / JUnit for a function like this:

我正在尝试使用 Mockito/JUnit 为这样的函数编写单元测试:

class1 {
 method {
  object1 = class2.method // method that I want to fake the return value
  // some code that I still want to run
 }
}

Is there any way in Mockito to stub the result of class2.method? I'm trying to improve code coverage for class1 so I need to call its real production methods.

Mockito 有没有办法存根 class2.method 的结果?我正在尝试提高 class1 的代码覆盖率,因此我需要调用其真正的生产方法。

I looked into the Mockito API at its spy method but that would overwrite the whole method and not the part that I want.

我在其 spy 方法中查看了 Mockito API,但这会覆盖整个方法而不是我想要的部分。

采纳答案by John Brumbaugh

I think I am understanding your question. Let me re-phrase, you have a function that you are trying to test and want to mock the results of a function called within that function, but in a different class. I have handled that in the following way.

我想我理解你的问题。让我重新表述一下,您有一个正在尝试测试的函数,并且想要模拟在该函数中调用的函数的结果,但在不同的类中。我是通过以下方式处理的。

public MyUnitTest {
    private static final MyClass2 class2 = mock(MyClass2.class);

    @Begin
    public void setupTests() {
        when(class2.get(1000)).thenReturn(new User(1000, "John"));
        when(class2.validateObject(anyObj()).thenReturn(true);
    }

    @Test
    public void testFunctionCall() {
        String out = myClass.functionCall();
        assertThat(out).isEqualTo("Output");
    }
}

What this is doing is that within the function wrapped with the @Before annotation, I am setting up how I want the functions in class2 to respond given specific inputs. Then, from within the actual test, I am just calling the function that I am trying to test in the class I want to test. In this case, the myClass.functionCall() is running through as normal and you are not overwriting any of its methods, but you are just mocking the outputs that it gets from the methods (or method) within MyClass2.

这样做是在用@Before 注释包裹的函数中,我正在设置我希望 class2 中的函数如何响应给定的特定输入。然后,在实际测试中,我只是在要测试的类中调用要测试的函数。在这种情况下, myClass.functionCall() 正常运行,您没有覆盖它的任何方法,但您只是在模拟它从 MyClass2 中的方法(或方法)获得的输出。

回答by krku

This Worked for Me:

这对我有用:

public class Class1Test {

  Class1 class1;

  @Before
  public void setUp() {
    MockitoAnnotations.initMocks(this);
    class1 = new Class1();
  }

  @Test
  public void testClass1Method() {

    Class2 class2 = Mockito.mock(Class2.class);
    class1.setClass2(class2);
    Mockito.when(
            class2.class2Method(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn("some response");

    String actualResponse = class1
            .class1Method("12345", "3333", "4444");
    assertEquals("some response", actualResponse);
  }
}

回答by Mori

I wrote a simple example which worked fine, hope it helps:

我写了一个简单的例子,效果很好,希望它有帮助:

method1() from Class1 calls method2() from Class2:

Class1 中的 method1() 调用 Class2 中的 method2():

    public class Class1 {
        private Class2 class2 = new Class2();
        public int method1() {
            return class2.method2();
        }
    }

Class2 and method2() :

Class2 和 method2() :

    public class Class2 {
        public int method2() {
            return 5;
        }
    }

And the Test:

和测试:

    import org.junit.Rule;
    import org.junit.Test;
    import org.mockito.InjectMocks;
    import org.mockito.Mock;
    import org.mockito.junit.MockitoJUnit;
    import org.mockito.junit.MockitoRule;

    import static org.junit.Assert.assertEquals;
    import static org.mockito.Mockito.when;

    public class TestClass1 {

        @Mock
        Class2 class2;

        @InjectMocks
        Class1 class1;

        @Rule
        public MockitoRule mockitoRule = MockitoJUnit.rule();

        @Test
        public void testMethod1(){
            when(class2.method2()).thenReturn(29);
            assertEquals(29,class1.method1());
        }
    }