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