Mockito / Junit5 org.opentest4j.AssertionFailedError for getter()
Mockito / Junit5 org.opentest4j.AssertionFailedError for getter()
如果我使用以下方法进行 JUnit Mockito 测试,它会失败并显示 org.opentest4j.AssertionFailedError: expected: not null。但是在使用 verify() 和 Assertions.assertNotNull() 之前的 Mockito-(Parameter-)Test 是可以的。我做错了什么或我不明白什么?这是我的代码:
JUnit5/mock-Test:
@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;
}
抱歉,您的测试代码实在是太复杂了。
它描述了被测方法中操作的对象的调用流程。
除了你模拟很多东西:依赖关系,被测方法的参数。
最后,您将被测方法的 return 分配给引用模拟参数的变量。这让事情真的不清楚。
测试必须简单明了,但事实并非如此。
我花了大约 500 万才了解错误原因。对于这么简单的代码来说已经很多了。
此断言失败:
Assertions.assertNotNull( myentityBmock.getMyentityA() ); // --> org.opentest4j.AssertionFailedError: expected: not <null>
是因为在测试方法中 getMynEntityA()
只能是 null
因为 myentityBmock
是一个 mock 并且设置一个字段就像你在这里做的那样不会影响真实字段和关联的 getter 行为:
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());
}
根本没有经过测试的代码,但它应该可以帮助您理解我的意图。
如果我使用以下方法进行 JUnit Mockito 测试,它会失败并显示 org.opentest4j.AssertionFailedError: expected: not null。但是在使用 verify() 和 Assertions.assertNotNull() 之前的 Mockito-(Parameter-)Test 是可以的。我做错了什么或我不明白什么?这是我的代码:
JUnit5/mock-Test:
@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;
}
抱歉,您的测试代码实在是太复杂了。
它描述了被测方法中操作的对象的调用流程。
除了你模拟很多东西:依赖关系,被测方法的参数。
最后,您将被测方法的 return 分配给引用模拟参数的变量。这让事情真的不清楚。
测试必须简单明了,但事实并非如此。
我花了大约 500 万才了解错误原因。对于这么简单的代码来说已经很多了。
此断言失败:
Assertions.assertNotNull( myentityBmock.getMyentityA() ); // --> org.opentest4j.AssertionFailedError: expected: not <null>
是因为在测试方法中 getMynEntityA()
只能是 null
因为 myentityBmock
是一个 mock 并且设置一个字段就像你在这里做的那样不会影响真实字段和关联的 getter 行为:
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());
}
根本没有经过测试的代码,但它应该可以帮助您理解我的意图。