是否有一种干净的方法来用泛型参数模拟类?假设我必须模拟一个类Foo<T>,我需要传递到一个方法,期望Foo<Bar>。我可以很容易地做到以下几点:
Foo mockFoo = mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());
假设getValue()返回泛型类型t,但当我后来将它传递给一个期望Foo<Bar>的方法时,它将有小猫。选角是唯一的方法吗?
是否有一种干净的方法来用泛型参数模拟类?假设我必须模拟一个类Foo<T>,我需要传递到一个方法,期望Foo<Bar>。我可以很容易地做到以下几点:
Foo mockFoo = mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());
假设getValue()返回泛型类型t,但当我后来将它传递给一个期望Foo<Bar>的方法时,它将有小猫。选角是唯一的方法吗?
当前回答
(在我看来)最简单和最易读的方法是使用方法级注入。
这将导致在测试方法中拥有所有测试数据。这将使您的测试类保持干净,因为没有“浮动”mock。
@ExtendWith(MockitoExtension.class)
public class SomeClassTest {
@Test
void someTestMethod(@Mock Foo<Bar> fooMock) {
// do something with your mock
}
}
其他回答
我认为你确实需要施放它,但这应该不会太糟:
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注释的字段。
为什么不用间谍
var mock = spy(new Foo<Bar>());
when(mockFoo.getValue()).thenReturn(new Bar());
所以你得到了这个:
Foo mockFoo = mock(Foo.class);
解决方法,从我最不喜欢的开始到最喜欢的:
使用@SuppressWarnings("unchecked")注释。这并不能真正解决问题,但你将不再收到警告。
@SuppressWarnings("unchecked")
Foo mockFoo = mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());
把它。不幸的是,它仍然给出了警告。所以你也需要在这里使用注释:
@SuppressWarnings("unchecked")
Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());
使用@Mock注释。不会有任何警告。这里,什么时候可以加入到实际测试中。
@Mock
public Foo<Bar> fooMock;
使用@MockBean注释。这将直接创建一个模拟bean。没有警告。
@MockBean
public Foo<Bar> fooMock;
我同意人们不应该在类或方法中压制警告,因为这样会忽略其他意外压制的警告。但是恕我直言,对于只影响一行代码的警告,不发出警告是完全合理的。
@SuppressWarnings("unchecked")
Foo<Bar> mockFoo = mock(Foo.class);