当我结合构造函数注入(子类)和属性注入(父类)时,@ InjectMocks给我空值

时间:2019-07-18 09:32:50

标签: java mockito

我有一个带有注入属性的摘要。这由子类扩展,在子类中通过构造函数完成注入。在单元测试中,@ 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.
    ...
  }  

}

1 个答案:

答案 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传递给超类。