为什么我的存根方法返回 null?
Why is my stubbed method returning null?
我有一个classDummy
。我注入了 3 个变量。但是,其中一个是不可注入的,因为它是一个接口。所以我注入了一个对象,其中一个方法 return 是所需的类型。
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
return 是 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
为空。我做错了什么?
@InjectMocks
发生在 @Before
注释之前。
出于这个原因(和 other reasons), I recommend not using @InjectMocks
at all; just build your SUT class 在 @Before
方法中使用真正的构造函数。
当您向测试添加一些打印语句时,此顺序很明显 class。我删除了所有 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()
return 成为模拟而不是 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
return null
以外的东西是部分模仿,因此他们不会喜欢它。
我有一个classDummy
。我注入了 3 个变量。但是,其中一个是不可注入的,因为它是一个接口。所以我注入了一个对象,其中一个方法 return 是所需的类型。
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
return 是 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
为空。我做错了什么?
@InjectMocks
发生在 @Before
注释之前。
出于这个原因(和 other reasons), I recommend not using @InjectMocks
at all; just build your SUT class 在 @Before
方法中使用真正的构造函数。
当您向测试添加一些打印语句时,此顺序很明显 class。我删除了所有 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()
return 成为模拟而不是 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
return null
以外的东西是部分模仿,因此他们不会喜欢它。