英文:
Mockito calls stubbed method even if using doReturn
问题
这是我的服务类,其中包含我想要进行存根化的方法调用。
public class ProjectService implements SomeInterfance {
// 第三方服务
private final DamConnector damConnector;
// 其他字段
public ProjectDTO save(ProjectDTO projectDTO) {
log.debug("Request to save Project : {}", projectDTO);
// 一些操作
synchronizeWithDamAndSave(project, parentChanging); // 这是我想要跳过的方法调用
// 其他操作
return projectMapper.toDto(project, this);
}
// 我想要存根化的方法
public Asset synchronizeWithDamAndSave(Project project, boolean includeDocuments) {
Asset asset = synchronizeWithDam(project, includeDocuments);
projectRepository.save(project);
return asset;
}
}
还有我的集成测试类:
@SpringBootTest(classes = SppApp.class)
public class ProjectResourceIT {
// 其他字段
// 由于我的服务需要进行服务调用,所以我使用了自动装配
@Autowired
private ProjectService projectService;
// 这是我的设置方法,在这里我创建了项目服务的 spy,并在调用我的方法时定义了 doReturn 的行为
@BeforeEach
public void setup() {
ProjectService spyProjectService = Mockito.spy(projectService);
Mockito.doReturn(new Asset()).when(spyProjectService).synchronizeWithDamAndSave(Mockito.any(Project.class), Mockito.anyBoolean());
MockitoAnnotations.initMocks(this);
final ProjectResource projectResource = new ProjectResource(spyProjectService, clientService, securityService);
this.restProjectMockMvc = MockMvcBuilders.standaloneSetup(projectResource)
.setCustomArgumentResolvers(pageableArgumentResolver)
.setControllerAdvice(exceptionTranslator)
.setConversionService(createFormattingConversionService())
.setMessageConverters(jacksonMessageConverter)
.setValidator(validator).build();
}
}
...
public void updateProject() throws Exception {
// 测试的初始化
// 这是我调用控制器的地方
restProjectMockMvc.perform(put("/api/projects")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(projectDTO)))
.andExpect(status().isOk());
}
}
在我这种情况下的问题是,Mockito 在调用以下行之后就进入了 synchronizeWithDamAndSave 方法:
Mockito.doReturn(new Asset()).when(spyProjectService).synchronizeWithDamAndSave(Mockito.any(Project.class), Mockito.anyBoolean());
这一行在方法从 REST API 调用之前被调用。关于为什么会发生这种情况,您应该怎么做,或者出现问题的可能原因,您有什么提示吗?
英文:
I want to create an integration test where a put method is called on a controller and it updates a certain object. During this process, a service class is involved which calls a third party API to do some stuff. In my case, I want to stub the service method which is involved in calling the third party as it is not the point to test the third party.
Having that said, I will present my code and I wait for an answer about why this does not work as expected and/or any other workaround.
This is my service class in which is the method call I want to stub.
public class ProjectService implements SomeInterfance {
// the third party service
private final DamConnector damConnector;
// some other fields
public ProjectDTO save(ProjectDTO projectDTO) {
log.debug("Request to save Project : {}", projectDTO);
// some operations
synchronizeWithDamAndSave(project, parentChanging); //this is the method call I want to be skiped
//other operations
return projectMapper.toDto(project, this);
}
//the method that I want to stub
public Asset synchronizeWithDamAndSave(Project project, boolean includeDocuments) {
Asset asset = synchronizeWithDam(project, includeDocuments);
projectRepository.save(project);
return asset;
}
}
And my integration test class:
@SpringBootTest(classes = SppApp.class)
public class ProjectResourceIT {
//other fields
//my service use autowire as it needs to make the service calls
@Autowired
private ProjectService projectService;
//this is my setup method where I create the spy of project service and define the doReturn behavior when my method is called
@BeforeEach
public void setup() {
ProjectService spyProjectService = Mockito.spy(projectService);
Mockito.doReturn(new Asset()).when(spyProjectService).synchronizeWithDamAndSave(Mockito.any(Project.class),Mockito.anyBoolean());
MockitoAnnotations.initMocks(this);
final ProjectResource projectResource = new ProjectResource(spyProjectService, clientService, securityService);
this.restProjectMockMvc = MockMvcBuilders.standaloneSetup(projectResource)
.setCustomArgumentResolvers(pageableArgumentResolver)
.setControllerAdvice(exceptionTranslator)
.setConversionService(createFormattingConversionService())
.setMessageConverters(jacksonMessageConverter)
.setValidator(validator).build();
}
}
...
public void updateProject() throws Exception {
// initialization of the test
// this is where I call my controller
restProjectMockMvc.perform(put("/api/projects")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(projectDTO)))
.andExpect(status().isOk());
}
}
The problem in my case is that mockito enters in synchronizeWithDamAndSave method just after
Mockito.doReturn(new Asset()).when(spyProjectService).synchronizeWithDamAndSave(Mockito.any(Project.class),Mockito.anyBoolean());
this line is called, before the method to be called from the rest api.
What should I do? Any hints about why this is happening?
答案1
得分: 1
Spring Boot的代理在与Mockito一起使用时无法正常工作。请使用@SpyBean替代@Autowired。
英文:
Spring Boot's proxies are not working wit Mockito. Use @SpyBean instead of @Autowired.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论