【发布时间】:2022-01-10 12:14:25
【问题描述】:
我有一个特殊情况,我不知道如何解决。
我正在使用 spring boot、junit 和 mockito 测试服务类方法。在我正在测试的类方法中,它也调用了一个内部方法,如下所示:
@Service
public class ServiceFacadeImpl implements ServiceFacade {
//Some autowire and stuffs
@Override
public List<Log> getObjectLog(String objectCode) {
List<Log> objectLogs = objectRepository.findByObjectCode(objectCode);
return objectLogs;
}
@Override
public MyObjectWrapper getMyObjectsLogByExternalCode(String externalCode) {
List<String> objectCodes = objectRepository.findobjectCodesByExternalCode(externalCode);
if(CollectionUtils.isEmpty(objectCodes)){
return null;
}
MyObjectWrapper wrapper = new MyObjectWrapper();
wrapper.setExternalCode(externalCode);
wrapper.setObjectLogs(new ArrayList<>());
for (String objectCode : objectCodes ) {
ObjectLogWrapper logWrapper = new ObjectLogWrapper();
List<Log> logs = getObjectLog(opCode); // Call to internal method of the class
logWrapper.setObjectCode(objectCode);
logWrapper.setObjectLog(logs);
wrapper.getObjectLogs().add(logWrapper);
}
return MyObjectWrapper ;
}
}
我试图在测试“getMyObjectsLogByExternalCode”方法时模拟这个 getObjectLog(opCode) 以根据收到的参数返回不同的日志列表
@SpringBootTest
@RunWith(SpringRunner.class)
class ObjectServiceFacadeImplTest {
//Some mock beans
@Autowired private ServiceFacade serviceFacade;
@Test
@DisplayName("test")
void testGetMyObjectsLogByExternalCode() {
// Given
List<String> mockObCodes = Arrays.asList( "obcode1","obcode2" );
when(repository.findObjectCodesByexternalCode(any())).thenReturn(mockObCodes );
List<OperationLogDTO> mockLogsOb1 = Arrays.asList( new Log(), new Log() ); //Size 2 for ob1
when(serviceFacade.getObjectLog(eq( "obcode1"))).thenReturn( mockLogsOb1 );
List<OperationLogDTO> mockLogsOb2 = Collections.singletonList( new Log() ); //Size 1 for ob1
when(serviceFacade.getObjectLog(eq( "obcode2"))).thenReturn( mockLogsOb2 );
// When
MyObjectWrapper objectWrapper = serviceFacade.getMyObjectsLogByExternalCode("TESTCODE");
// Then
assertEquals( objectWrapper.getExternalCode(),"TESTCODE" );
assertEquals( objectWrapper.getObjects().size(),2 );
assertEquals( objectWrapper.getObjects().get( 0 ).getLogs().size(),2 ); //Fails because it gets the second mock return value
assertEquals( objectWrapper.getObjects().get( 0 ).getCode(),"obcode1" ); //Fails because it gets the second mock return value
assertEquals( objectWrapper.getObjects().get( 1 ).getLogs().size(),1 );
assertEquals( objectWrapper.getObjects().get( 1 ).getCode(),"obcode2" );
}
由于机密内容,代码已更改,但我认为我正在尝试做的事情的逻辑很清楚
逻辑基本上是我有包含次要对象的主要对象,而这个次要对象也包含日志对象。有一种方法可以获取每个辅助对象的日志,另一种方法可以提供主对象代码,它会获取与包装对象关联的所有辅助对象的所有日志以及所有信息。
这里的问题是,当 getObjectLogs 作为模拟调用时,总是不雅地返回接收到的参数的第二种情况。调用它时,我总是丢失大小为 1 的日志。
我不知道我做错了什么。
更新:
我也尝试使用@SpyBean 而不是@Autowired 来提供服务,但它总是返回相同的
@SpyBean private ServiceFacade serviceFacade;
【问题讨论】:
-
您的测试中有
serviceFacade和operationServiceFacade,哪一个是正确的?此外,由于您是自动接线serviceFacade,因此您将无法模拟任何有关它的内容。 -
@JoãoDias 我编辑了失败。
-
@JoãoDias 我知道我正在自动装配它,但我还需要模拟一个额外的方法,那么我该怎么做呢?它似乎也在嘲笑它,但总是返回 obcode2 响应
-
您可以尝试使用 Spy,但模拟
getObjectLog方法中的任何内容听起来会更好。由于您没有提供它的代码,我们仍然无法为您提供帮助。 -
能否请附上
getMyObjectsLogByExternalCode和getObjectLog的完整代码?谢谢。
标签: spring-boot unit-testing junit mockito arguments