使用Mockito模拟具有通用参数的类

有没有一个干净的方法嘲笑类与generics参数? 说我必须嘲笑类Foo<T> ,我需要传递到一个方法,期望Foo<Bar> 。 我可以很容易地做到以下几点:

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

假设getValue()返回genericstypesT 但是当我稍后把它传递给一个期望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初始化用@Mock注解的字段。

您可以始终创build一个中间类/接口,以满足您希望指定的genericstypes。 例如,如果Foo是一个接口,则可以在testing类中创build以下接口。

 private interface FooBar implements Foo<Bar> { } 

在Foo是一个非final类的情况下,你可以用下面的代码扩展这个类并做同样的事情:

 public class FooBar extends Foo<Bar> { } 

然后你可以使用下面的代码来使用上面的例子:

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

创build一个testing工具方法 。 特别有用,如果你需要它不止一次。

 @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); } 

下面是一个有趣的例子:方法接受generics集合并返回相同基types的generics集合。 例如:

 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>(); } });