Как сказать объекту Mockito mock вернуть что-то другое при следующем вызове?
Итак, я создаю макет объекта в статическую переменную на уровне класса так... В одном тесте, я хочу!--1--> чтобы вернуть определенное значение, в то время как в другом тесте, я хочу, чтобы возвращать разные значения. Проблема в том, что мне кажется, что мне нужно перестроить насмешки, чтобы заставить это работать правильно. Я бы хотел избежать перестройки насмешек и просто использовать одни и те же объекты в каждом тесте.
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.
}
}
во втором тесте, я все еще получаю 0 как значение, когда testObj.бар() называется... Что это лучший способ решить это? Обратите внимание, что я знаю, что могу использовать другой макет Foo
в каждом тесте, однако, я должен связать несколько запросов с mockFoo
, что означает, что мне придется делать цепочку в каждом тесте.
4 ответов
прежде всего, не делайте макет статической. Пусть это будет частное поле. Просто поместите свой класс установки в @Before
не @BeforeClass
. Может, и много, но дешево.
во-вторых, так вы его сейчас правильно сделать макет, чтобы вернуть что-то другое в зависимости от теста.
вы также могли бы Заглушка Последовательных Вызовов (#10 в 2.8.9 api). В этом случае можно использовать несколько 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
}
}
для всех, кто ищет, чтобы вернуть что-то, а затем для другого исключения вызова:
when(mockFoo.someMethod())
.thenReturn(obj1)
.thenReturn(obj2)
.thenThrow(new RuntimeException("Fail"));
или
when(mockFoo.someMethod())
.thenReturn(obj1, obj2)
.thenThrow(new RuntimeException("Fail"));
для тех, кто использует spy () и doReturn () вместо метода when ():
что вам нужно, чтобы вернуть другой объект при разных вызовах, это:
doReturn(obj1).doReturn(obj2).when(this.client).someMethod();