كيف تخبر كائن Mockito Mock لإعادة شيء مختلف في المرة القادمة التي يطلق عليها؟
-
26-09-2019 - |
سؤال
لذا ، أقوم بإنشاء كائن وهمية كمتغير ثابت على مستوى الفصل مثل ذلك ... في اختبار واحد ، أريد 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.
}
}
في الاختبار الثاني ، ما زلت أتلقى 0 كقيمة عندما تسمى testobj.bar () ... ما هي أفضل طريقة لحل هذا؟ لاحظ أنني أعلم أنه يمكنني استخدام وهمية مختلفة من Foo
ومع ذلك ، في كل اختبار ، يجب عليّ ربط طلبات متعددة mockFoo
, ، وهذا يعني أنني يجب أن أفعل التسلسل في كل اختبار.
المحلول
بادئ ذي بدء ، لا تجعل الوهمية ثابتة. اجعله حقلًا خاصًا. فقط ضع فصل الإعداد الخاص بك في @Before
ليس @BeforeClass
. قد يتم تشغيل حفنة ، لكنها رخيصة.
ثانياً ، الطريقة التي لديك بها الآن هي الطريقة الصحيحة للحصول على وهمية لإعادة شيء مختلف اعتمادًا على الاختبار.
نصائح أخرى
هل يمكن أيضا مكالمات متتالية على التوالي (#10 في 2.8.9 API). في هذه الحالة ، ستستخدم عدة ثم مكالمات أو واحدة ثم استدعاء مع معلمات متعددة (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"));
أو حتى أنظف:
when(mockFoo.someMethod()).thenReturn(obj1, obj2);
لأي شخص يستخدم spy () و doreturn () بدلاً من طريقة () طريقة:
ما تحتاجه لإرجاع كائن مختلف على مكالمات مختلفة هو:
doReturn(obj1).doReturn(obj2).when(this.client).someMethod();