我有一个班级假人.我注入3个变量.但是,其中一个不能注射,因为它是一个界面.所以我注入一个对象,其中一个方法返回所需的类型.
Class Dummy
{
private final Class1 class1;
private final Class2 class2
private final Interface1 interface1;
@Inject
Dummy(Class1 class1, Class2 class2, HelperClass helperclass)
{
this.class1 = class1;
this.class2 = class2;
this.interface1 = helperclass.somefunction();
}
}
HelperClass的somefunction返回Interface1的一个实例.
这是我的测试:
@RunWith(MockitoJUnitRunner.class)
Class DummyTest
{
@Mock
private Class1 class1;
@Mock
private Class2 class2;
@Mock
private HelperClass helperclass;
@InjectMocks
private Dummy dummy;
@Before
public void start()
{
Interface1 mockInterface = mock(Interface1.class);
when(helperclass.somefunction()).thenReturn(mockInterface);
}
@Test
public void test()
{
// etc...
}
}
但是,当我运行测试时,interface1为null.我究竟做错了什么?
解决方法:
@InjectMocks发生在@Before注释之前.
出于这个原因(和other reasons),我建议不要使用@InjectMocks;用真正的构造函数在@Before方法中构建你的SUT类.
当您向测试类添加一些print语句时,这种排序很明显.我删除了所有Class1和Class2的东西,因为它不相关.看到这个代码运行:
@RunWith(MockitoJUnitRunner.class)
public class DummyTest {
@Mock
private HelperClass helperclass;
@InjectMocks
private Dummy dummy;
@Before
public void start()
{
System.out.println("In @Before!");
Interface1 mockInterface = mock(Interface1.class);
when(helperclass.somefunction()).thenReturn(mockInterface);
}
@Test
public void test()
{
System.out.println("In @Test!");
}
public static class Dummy {
public final Interface1 interface1;
public final HelperClass helperclass;
@Inject
Dummy(HelperClass helperclass)
{
System.out.println("In dummy constructor!");
this.interface1 = helperclass.somefunction();
this.helperclass = helperclass;
}
}
private static class HelperClass {
Interface1 somefunction() {
return new Interface1() {};
}
}
private static interface Interface1 {
}
}
输出:
In dummy constructor!
In @Before!
In @Test!
如果您坚持使用@Mock和@InjectMocks,您可以尝试使用answer参数:
@Mock(answer=Answers.RETURNS_MOCKS)
将使helperclass.somemethod()返回一个mock而不是null.
老实说,它以这种方式工作并不奇怪. Mockito的作者真的不喜欢Partial Mocks / Stubs,并且明确地这样说in their documentation:
As usual you are going to read the partial mock warning: Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects. How does partial mock fit into this paradigm? Well, it just doesn’t… Partial mock usually means that the complexity has been moved to a different method on the same object. In most cases, this is not the way you want to design your application.
However, there are rare cases when partial mocks come handy: dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.) However, I wouldn’t use partial mocks for new, test-driven & well-designed code.
让helperclass返回null以外的东西是部分mock,因此他们不喜欢它.