【问题标题】:Mockito calls stubbed method even if using doReturn即使使用 doReturn,Mockito 也会调用存根方法
【发布时间】:2020-10-19 12:15:12
【问题描述】:

我想创建一个集成测试,其中在控制器上调用 put 方法并更新某个对象。在这个过程中,涉及到一个服务类,它调用第三方 API 来做一些事情。就我而言,我想存根调用第三方所涉及的服务方法,因为这不是测试第三方的重点。

话虽如此,我将展示我的代码,并等待有关为什么它不能按预期工作和/或任何其他解决方法的答案。

这是我的服务类,其中是我要存根的方法调用。

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;
    }

}

还有我的集成测试类:

@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());
    }

}

在我的情况下,问题是 mockito 在 synchronizeWithDamAndSave 方法之后进入

Mockito.doReturn(new Asset()).when(spyProjectService).synchronizeWithDamAndSave(Mockito.any(Project.class),Mockito.anyBoolean());

在要从其余 api 调用的方法之前调用此行。

我该怎么办?关于为什么会发生这种情况的任何提示?

【问题讨论】:

  • Mockito.spy 正在包装实例,它仍然会调用实现(除非被覆盖)。您可能想使用 Mockito.mock?
  • 我知道这会调用实现,这就是为什么我用 mockito doReturn 覆盖它......when。这不就是这个方法的作用吗? @Jayr

标签: java spring-boot mockito integration-testing


【解决方案1】:

Spring Boot 的代理不适用于 Mockito。使用@SpyBean 而不是@Autowired。

【讨论】:

  • 非常感谢您的回答,你是对的,mockito 不能与代理一起工作,所以 SpyBean 是解决方案
  • 抱歉 Oncioiu 你是对的,@rmunge 的答案一定是正确的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多