كيف تخبر كائن Mockito Mock لإعادة شيء مختلف في المرة القادمة التي يطلق عليها؟

StackOverflow https://stackoverflow.com/questions/4216569

سؤال

لذا ، أقوم بإنشاء كائن وهمية كمتغير ثابت على مستوى الفصل مثل ذلك ... في اختبار واحد ، أريد 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();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top