代码之家  ›  专栏  ›  技术社区  ›  DigitalZebra

如何告诉Mockito mock对象在下次调用时返回不同的对象?

  •  160
  • DigitalZebra  · 技术社区  · 15 年前

    所以,我正在创建一个模拟对象作为类级别上的静态变量,就像这样。。。在一次测试中,我想 Foo.someMethod() 要返回某个值,而在另一个测试中,我希望它返回不同的值。我遇到的问题是,我似乎需要重新构建mocks以使其正常工作。我希望避免重建模拟,只在每个测试中使用相同的对象。

    class TestClass {
    
        private static Foo mockFoo;
    
        @BeforeClass
        public static void setUp() {
            mockFoo = mock(Foo.class);
        }
    
        @Test
        public void test1() {
            when(mockFoo.someMethod()).thenReturn(0);
    
            TestObject testObj = new TestObject(mockFoo);
    
            testObj.bar(); // calls mockFoo.someMethod(), receiving 0 as the value
    
        }
    
        @Test
        public void test2() {
            when(mockFoo.someMethod()).thenReturn(1);
    
            TestObject testObj = new TestObject(mockFoo);
    
            testObj.bar(); // calls mockFoo.someMethod(), STILL receiving 0 as the value, instead of expected 1.
    
        }
    
    }
    

    在第二个测试中,当调用testObj.bar()时,我仍然接收0作为值。。。解决这个问题的最好方法是什么?注意,我知道我可以用一个不同的模仿 Foo 但是,在每个测试中,我必须将多个请求从 mockFoo ,也就是说每次考试我都要做链子测试。

    5 回复  |  直到 15 年前
        1
  •  42
  •   shoebox639    15 年前

    首先不要让模拟静态化。把它变成一个私人领域。把你的安装课程放在 @Before 不 @BeforeClass . 可能是一堆,但很便宜。

    其次,现在的方法是让mock根据测试返回不同的内容的正确方法。

        2
  •  413
  •   Freek de Bruijn    9 年前

    你也可以 Stub Consecutive Calls (api 2.8.9中的10)。在这种情况下,可以使用多个 然后返回 打电话还是打一个 然后返回 使用多个参数(varargs)调用。

    import static org.junit.Assert.assertEquals;
    import static org.mockito.Mockito.mock;
    import static org.mockito.Mockito.when;
    
    import org.junit.Before;
    import org.junit.Test;
    
    public class TestClass {
    
        private Foo mockFoo;
    
        @Before
        public void setup() {
            setupFoo();
        }
    
        @Test
        public void testFoo() {
            TestObject testObj = new TestObject(mockFoo);
    
            assertEquals(0, testObj.bar());
            assertEquals(1, testObj.bar());
            assertEquals(-1, testObj.bar());
            assertEquals(-1, testObj.bar());
        }
    
        private void setupFoo() {
            mockFoo = mock(Foo.class);
    
            when(mockFoo.someMethod())
                .thenReturn(0)
                .thenReturn(1)
                .thenReturn(-1); //any subsequent call will return -1
    
            // Or a bit shorter with varargs:
            when(mockFoo.someMethod())
                .thenReturn(0, 1, -1); //any subsequent call will return -1
        }
    }
    
        3
  •  19
  •   Nagy Attila    8 年前

    对于所有搜索返回某些内容,然后搜索另一个调用引发异常的用户:

        when(mockFoo.someMethod())
                .thenReturn(obj1)
                .thenReturn(obj2)
                .thenThrow(new RuntimeException("Fail"));
    

    或

        when(mockFoo.someMethod())
                .thenReturn(obj1, obj2)
                .thenThrow(new RuntimeException("Fail"));
    
        4
  •  10
  •   pedromorfeu    7 年前

    或者,甚至更干净:

    when(mockFoo.someMethod()).thenReturn(obj1, obj2);
    
        5
  •  9
  •   fl0w    6 年前

    任何使用spy()的人 以及doReturn()而不是when()方法:

    要在不同的调用中返回不同的对象,需要执行以下操作:

    doReturn(obj1).doReturn(obj2).when(this.client).someMethod();
    

    .

    对于经典的模仿:

    when(this.client.someMethod()).thenReturn(obj1, obj2);