Junit Mockito NullPointerException for Mock 用于基于构造函数的自动装配

Posted

技术标签:

【中文标题】Junit Mockito NullPointerException for Mock 用于基于构造函数的自动装配【英文标题】:Junit Mockito NullPointerException for Mock for constructor based autowiring 【发布时间】:2019-04-22 13:22:42 【问题描述】:

我正在尝试测试实现类,其中我正在为接口创建基于构造函数的自动装配。 我不打算改变这个类或它的自动装配方式。

在为实现类编写测试用例时,我收到 NullPointerException,因为在实现类中创建了对象 具有不同的对象引用,模拟对象具有不同的引用值。

谁能告诉我如何模拟这个对象。

实现类

public class ImplementationClass implements ClientClass 

private final RepositoryInterface repositoryInterface;
@Autowired
public ImplementationClass( RepositoryInterface repositoryInterface ) 
    this.repositoryInterface = repositoryInterface;

@Autowired
AAA aaa;

@Autowired
BBB bbb;

@Autowired
CCC ccc;

public DomainClass getDetails( String Id ) 
    // aaa, bbb, ccc usage
    DomainClass getDetDocument =
        repositoryInterface.findById( Id ).orElse( null );


单元测试类

@Mock
RepositoryInterface repositoryInterface;

@Mock
DomainClass DomainClass;

@Mock
AAA aaa;

@Mock
BBB bbb;

@Mock
CCC ccc;

@InjectMocks
ImplementationClass implementationClass;

@Before
public void setUp() 
    MockitoAnnotations.initMocks( this );
    

 @Test
public void getDetTest() 
DomainClass dc = new DomainClass();
    dc.setId( "Id-123456789" );
    dc.setDetailsList( <Some list> );

    Optional<DomainClass> c1 = Optional.of( dc );
    // when().thenReturn(); // aaa, bbb, ccc usage
when( repositoryInterface.findById( "Id-123456789" )).thenReturn( c1 );
    DomainClass c2 = implementationClass.getDetails( "Id-123456789" );

    assertThat( c2.getDetailsList(), equalTo( c1.getDetailsList() ) );

更新:在调试测试类时,对象 repositoryInterface when( repositoryInterface.findById( "Id-123456789" )).thenReturn( c1 ); 创建一个参考值 (23425634534@2005) 并且当 ImplementationClass 被称为 repositoryInterface DomainClass getDetDocument =repositoryInterface.findById( Id ).orElse( null ); 在 ImplementationClass 中有一个参考值 (23425634534@1879)。因此,我为 getDetDocument 获得了null

【问题讨论】:

询问异常时,总是发布异常的完整堆栈跟踪。 这是我在控制台中遇到的用户定义异常。但是在调试时,我得到了实现类中语句DomainClass getDetDocument = repositoryInterface.findById( Id ).orElse( null );null 值。那是因为,repositoryInterface 对象引用值在实现类和测试类中是不同的。 【参考方案1】:

经过所有研究,通过更改构造函数创建对象的方式使其工作。

// @Mock //removed this annotation
   RepositoryInterface repositoryInterface;


@Before
   public void setUp() 
     repositoryInterface = mock(RepositoryInterface.class)
     ImplementationClass = new ImplementationClass(repositoryInterface);
     MockitoAnnotations.initMocks( this );

参考:https://mhaligowski.github.io/blog/2014/05/30/mockito-with-both-constructor-and-field-injection.html

【讨论】:

以上是关于Junit Mockito NullPointerException for Mock 用于基于构造函数的自动装配的主要内容,如果未能解决你的问题,请参考以下文章

JUnit + Mockito 单元测试

如何使用 mockito 和 junit 测试此功能?

Junit/Mockito:选择使用模拟或集成测试运行测试

Mockito & Junit 空指针异常:名称不能为空

简单的 Mockito 验证在 JUnit 中有效,但在 Spock 中无效

如何在 JUnit Test Java 中替换 Mockito 以存根类