باستخدام Mockito تسخر الطبقات مع المعلمات عامة

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

  •  22-07-2019
  •  | 
  •  

سؤال

هل هناك طريقة نظيفة من الاستهزاء فئة مع عامة المعلمات ؟ أقول يجب أن تسخر فئة Foo<T> التي تحتاج إلى تمرير في الطريقة التي تتوقع Foo<Bar>.أنا يمكن أن تفعل ما يلي بسهولة بما فيه الكفاية:

Foo mockFoo = mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());

على افتراض getValue() إرجاع نوع عام T.ولكن الذي يحدث أن القطط عندما كنت في وقت لاحق تمريرها إلى الأسلوب تتوقع Foo<Bar>.صب فقط يعني من فعل هذا ؟

هل كانت مفيدة؟

المحلول

وأعتقد أنك بحاجة ليلقي عليه، ولكن لا ينبغي أن يكون سيئا للغاية:

Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());

نصائح أخرى

وثمة طريقة أخرى لتجنب ذلك هي استخدام @Mock الشرح بدلا من ذلك. لا يعمل في جميع الحالات، ولكن يبدو أكثر جنسية من ذلك بكثير:)

وهنا مثال:

@RunWith(MockitoJUnitRunner.class)
public class FooTests {

    @Mock
    public Foo<Bar> fooMock;

    @Test
    public void testFoo() {
        when(fooMock.getValue()).thenReturn(new Bar());
    }
}

MockitoJUnitRunner تهيئة الحقول المشروح مع <ل أ href = "https://mockito.googlecode.com/svn/tags/latest/javadoc/org/mockito/Mockito.html#9"> @Mock .

يمكنك دائما إنشاء الطبقة المتوسطة/واجهة ترضي عامة النوع الذي كنت ترغب في تحديد ذلك.على سبيل المثال ، إذا فو كان واجهة ، يمكن إنشاء واجهة التالية في اختبار الصف.

private interface FooBar extends Foo<Bar>
{
}

في الحالات التي يكون فيها فو هو غير النهائية الدرجة, هل يمكن أن مجرد تمديد الفصل مع التعليمات البرمجية التالية و تفعل نفس الشيء:

public class FooBar extends Foo<Bar>
{
}

ثم هل يمكن أن تستهلك إما من الأمثلة المذكورة أعلاه مع التعليمات البرمجية التالية:

Foo<Bar> mockFoo = mock(FooBar.class);
when(mockFoo.getValue()).thenReturn(new Bar());

إنشاء <م> طريقة الاختبار فائدة . مفيدة بشكل خاص إذا كنت في حاجة إليها لأكثر من مرة واحدة.

@Test
public void testMyTest() {
    // ...
    Foo<Bar> mockFooBar = mockFoo();
    when(mockFooBar.getValue).thenReturn(new Bar());

    Foo<Baz> mockFooBaz = mockFoo();
    when(mockFooBaz.getValue).thenReturn(new Baz());

    Foo<Qux> mockFooQux = mockFoo();
    when(mockFooQux.getValue).thenReturn(new Qux());
    // ...
}

@SuppressWarnings("unchecked") // still needed :( but just once :)
private <T> Foo<T> mockFoo() {
    return mock(Foo.class);
}

وهنا هو حالة مثيرة للاهتمام: طريقة receieves جمع عام وإرجاع مجموعة عامة من النوع الأساسي نفسه. على سبيل المثال:

Collection<? extends Assertion> map(Collection<? extends Assertion> assertions);

ويمكن أن سخر هذا الأسلوب مع مزيج من Mockito anyCollectionOf المنظر والإجابة.

when(mockedObject.map(anyCollectionOf(Assertion.class))).thenAnswer(
     new Answer<Collection<Assertion>>() {
         @Override
         public Collection<Assertion> answer(InvocationOnMock invocation) throws Throwable {
             return new ArrayList<Assertion>();
         }
     });

وأوافق على أن لا ينبغي للمرء أن قمع تحذيرات في الطبقات أو أساليب واحدة يمكن أن نغفل أخرى، تحذيرات قمعها عن طريق الخطأ. لكن IMHO انها معقولة على الاطلاق لقمع تحذيرا من أن يؤثر فقط على سطر واحد من التعليمات البرمجية.

@SuppressWarnings("unchecked")
Foo<Bar> mockFoo = mock(Foo.class);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top