我有一个带有注入属性的摘要。这由子类扩展,在子类中通过构造函数完成注入。在单元测试中,@ InjectMocks为注入到抽象类中的属性提供了空值。
请参见下面的代码。
我想了解为什么@InjectMocks在这种特定情况下不知道要从抽象类中注入属性。 有人可以帮助我理解吗? 非常感谢!!!
如果子类和父类都使用属性注入,则我的单元测试可以正常工作。
public abstract class AbstractClass
{
@Inject
private D d;
...
}
@RequestScoped
public class ConcreteClass extends AbstractClass
{
private A a;
private B b;
private C c;
@Inject
public ConcreteClass(A a, B b, C c)
{
this.a = a;
this.b = b;
this.c = c;
}
/**
* CDI, no arguments constructor.
*/
public ConcreteClass()
{
// CDI constructor
}
}
@RunWith(Theories.class)
public class ConcreteClassTest
{
@Mock
D d;
@Mock
A a;
@InjectMocks
ConcreteClass concreteClass;
@Before
public void setUp() throws Exception
{
...
MockProvider.setMockForClass(A.class, a);
MockProvider.setMockForClass(D.class, d);
...
}
@Theory
public void testMethod()
{
...
concreteClass.methodXXX();
//here if i inspect the concreteClass i see that the attribute "a" has value and attribute "d" is null.
...
}
}
答案 0 :(得分:1)
来自Mockito文档:
https://static.javadoc.io/org.mockito/mockito-core/3.0.0/org/mockito/InjectMocks.html
构造函数注入;选择最大的构造函数,然后仅使用在测试中声明的模拟来解析参数。如果使用构造函数成功创建了对象,则Mockito将不会尝试其他策略。 Mockito决定不破坏具有参数构造函数的对象。
由于您的构造函数只有A,B,C的Mockito不会处理D。 (不考虑属性或现场注入)
您可以更改构造函数,使其具有所有4个值,并将D传递给超类。