350

ジェネリックパラメーターを使用してクラスをモックするクリーンなメソッドはありますか?Foo<T>を期待するメソッドに渡す必要のあるクラスをモックする必要があるとしFoo<Bar>ます。私は次のことを簡単に行うことができます:

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

getValue()ジェネリック型を返すと仮定しますT。しかし、後でそれを期待するメソッドに渡すと、子猫が生まれFoo<Bar>ます。これを行う唯一の手段はキャストですか?

4

10 に答える 10

337

キャストする必要があると思いますが、それほど悪くはありません。

Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
when(mockFoo.getValue()).thenReturn(new Bar());
于 2009-10-30T23:12:38.040 に答える
323

これを回避するもう 1 つの方法は、@Mock代わりに注釈を使用することです。すべてのケースで機能するわけではありませんが、よりセクシーに見えます :)

次に例を示します。

@RunWith(MockitoJUnitRunner.class)
public class FooTests {

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

MockitoJUnitRunner、 で注釈が付けられたフィールドを初期化します@Mock

于 2011-04-16T15:00:12.927 に答える
54

指定したいジェネリック型を満たす中間クラス/インターフェースをいつでも作成できます。たとえば、Foo がインターフェイスの場合、テスト クラスで次のインターフェイスを作成できます。

private interface FooBar extends Foo<Bar>
{
}

Foo が最終クラスではない状況では、次のコードを使用してクラスを拡張し、同じことを行うことができます。

public class FooBar extends Foo<Bar>
{
}

次に、次のコードで上記の例のいずれかを使用できます。

Foo<Bar> mockFoo = mock(FooBar.class);
when(mockFoo.getValue()).thenReturn(new Bar());
于 2014-04-28T19:04:08.203 に答える
21

テスト ユーティリティ メソッドを作成します。複数回必要な場合に特に便利です。

@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);
}
于 2015-09-16T18:11:33.477 に答える
4

ここに興味深いケースがあります: メソッドはジェネリック コレクションを受け取り、同じ基本型のジェネリック コレクションを返します。例えば:

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

このメソッドは、Mockito anyCollectionOf マッチャーと Answer の組み合わせでモックできます。

when(mockedObject.map(anyCollectionOf(Assertion.class))).thenAnswer(
     new Answer<Collection<Assertion>>() {
         @Override
         public Collection<Assertion> answer(InvocationOnMock invocation) throws Throwable {
             return new ArrayList<Assertion>();
         }
     });
于 2015-09-03T11:59:57.853 に答える
3

JUnit5:@ExtendWith(MockitoExtension.class)テスト クラスで使用し、次のフィールドを追加します。

@Mock
Foo<Bar> barMock;
于 2021-03-09T14:59:25.500 に答える