用于getter()的Mockito / Junit5 org.opentest4j.AssertionFailedError

时间:2018-12-06 12:46:08

标签: java mockito junit5

如果我通过以下方法进行JUnit Mockito测试,则测试失败,并出现 org.opentest4j.AssertionFailedError:期望:不为空。但是之前使用verify()和Assertions.assertNotNull()的Mockito-(Parameter-)Test可以。我做错了什么或我不理解的是什么?这是我的代码:

JUnit5 /模拟测试:

@Mock
private MyentityAServiceImpl myentityAServiceImplmock;
@Captor
private ArgumentCaptor<MyentityA> myentityAArgument;
@Mock
private MyentityBdao myentityBdaomock;
@Mock
private MyentityB myentityBmock;
@Mock
private Logger loggermock;
@InjectMocks
private MyentityBServiceImpl teServiceImpl;

@Test
public void setMyentityAOfTeIfNullByLanr17() {
    myentityBmock.setLanr7( "1234567" );
    final MyentityA myentityA = new MyentityA();
    mockito.when( myentityAServiceImplmock.findMyentityAByLanr17( myentityBmock.getLanr7() ) ).thenReturn( myentityA );
    mockito.when( myentityBdaomock.save( myentityBmock ) ).thenReturn( myentityBmock );
    myentityBmock = teServiceImpl.setMyentityAOfTeIfNullByLanr17( myentityBmock );
    mockito.verify( myentityBmock ).setMyentityA( myentityAArgument.capture() );
    Assertions.assertNotNull( myentityAArgument );
    Assertions.assertNotNull( myentityBmock.getMyentityA() );  // --> org.opentest4j.AssertionFailedError: expected: not <null>
}

测试方法:

  public MyentityB setMyentityAOfTeIfNullByLanr17( final MyentityB entity ) {
    MyentityA myentityA = entity.getMyentityA();
    if ( myentityA != null ) {
        return entity;
    }
    final String lanr17 = entity.getLanr7();
    myentityA = myentityAServiceImpl.findMyentityAByLanr17( lanr17 );
    if ( myentityA != null ) {
        entity.setMyentityA( myentityA );
        entity.setModuser( "root" );
        return myentityBdao.save( entity );
    }
    return entity;
}

1 个答案:

答案 0 :(得分:3)

对不起,您的测试代码确实太复杂了。
它过于精细地描述了在测试方法中操作的对象的调用流程。
除了模拟之外,还包括很多东西:依赖项,被测方法的参数。
最后,将被测试方法的返回值分配给引用模拟参数的变量。这使事情真的不清楚。

测试必须是可以直接理解的,而事实并非如此。
我花了大约500万来了解错误原因。这样的简单代码很多。

此断言失败:

Assertions.assertNotNull( myentityBmock.getMyentityA() );  // --> org.opentest4j.AssertionFailedError: expected: not <null>

是由于以下事实:在经过测试的方法getMynEntityA()中只能是null,因为myentityBmock是模拟的,因此像在此处设置字段一样,对实数没有影响。字段和相关的吸气剂行为:

if ( myentityA != null ) {
    entity.setMyentityA( myentityA ); // here you invoke a mocked method.
    entity.setModuser( "root" );
    return myentityBdao.save( entity );
}

实际上,您的测试方法主要描述了被测试方法的调用流程,就足够了:

mockito.verify( myentityBmock ).setMyentityA( myentityAArgument.capture() );

因为您无法测试setMyentityA()的副作用。

但实际上,我强烈建议您在不模拟所测试方法的参数的情况下对您的方法进行单元测试。
它可能看起来像:

@Test
public void setMyentityAOfTeIfNullByLanr17() {
    MyentityB entityB = new MyentityB(...) ;
    entityB.setLanr7( "1234567" );
    final MyentityA myentityA = new MyentityA();
    mockito.when( myentityAServiceImplmock.findMyentityAByLanr17( entityB.getLanr7() ) ).thenReturn( myentityA );
    mockito.when( myentityBdaomock.save(entityB) ).thenReturn(entityB);

    // action
    MyentityB entityActualB = teServiceImpl.setMyentityAOfTeIfNullByLanr17(entityB);

    // Perform content/logic assertion and no flow assertion :
    Assertions.assertEquals(myEntityA, entityActualB.getMyEntityA());
    Assertions.assertEquals("root", entityActualB.getModuser());
}

完全没有经过测试的代码,但是它应该可以帮助您了解我的意图。