所以,我正在创建一个模拟对象作为类级别的静态变量,如此...在一次测试中,我希望Foo.someMethod()
返回一定值,而在另一个测试中,我想要它返回不同的值。我遇到的问题是,似乎我需要重建模拟才能使其正常工作。我想避免重建模拟,并在每次测试中使用相同的对象。
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
,这意味着我必须在每个测试中进行链接。< / p>
答案 0 :(得分:390)
你也可以Stub Consecutive Calls(2.8.9 api中的#10)。在这种情况下,您可以使用多个 thenReturn 调用或一个 thenReturn 调用多个参数(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
}
}
答案 1 :(得分:40)
首先不要让模拟静态。使它成为一个私人领域。只需将您的setUp类放入@Before
而不是@BeforeClass
。它可能会运行一堆,但它很便宜。
其次,你现在拥有它的方法是让模拟根据测试返回不同内容的正确方法。
答案 2 :(得分:8)
对于所有搜索返回内容然后进行另一次调用的人抛出异常:
when(mockFoo.someMethod())
.thenReturn(obj1)
.thenReturn(obj2)
.thenThrow(new RuntimeException("Fail"));
或
when(mockFoo.someMethod())
.thenReturn(obj1, obj2)
.thenThrow(new RuntimeException("Fail"));
答案 3 :(得分:5)
Or, even cleaner:
when(mockFoo.someMethod()).thenReturn(obj1, obj2);
答案 4 :(得分:4)
对于使用spy()和doReturn()而不是when()方法的任何人:
在不同的调用中返回不同对象需要的是:
doReturn(obj1).doReturn(obj2).when(this.client).someMethod();