spring 服务的@MockBean返回真实的示例,而不是@WebMvcTest中的mock

svmlkihl  于 12个月前  发布在  Spring
关注(0)|答案(1)|浏览(105)

所以我在@WebMvcTest下进行测试,我刚刚注意到我的服务的mocking使用@MockBean,我的控制器使用,不工作。我真的不知道该怎么办。我用的是Sping Boot 3.1.2有些东西是西班牙语的。是这样的:

@RestController
public class ClienteController implements IClienteController {

    private final ClienteService clienteService;
    private final CircuitBreakerRegistry circuitBreakerRegistry;

    @Autowired
    public ClienteController(ClienteService clienteService, CircuitBreakerRegistry circuitBreakerRegistry) {
        this.clienteService = clienteService;
        this.circuitBreakerRegistry = circuitBreakerRegistry;
    }

    @CircuitBreaker(name = "clienteCircuitBreaker", fallbackMethod = "fallbackCircuitBreaker")
    @Retry(name="clienteRetry")
    @RateLimiter(name="clienteRateLimiter", fallbackMethod = "fallbackRateLimiter")
    @GetMapping
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ClienteModel getCliente(@RequestParam int tipoDocumento, @RequestParam long nroDocumento) {
        return clienteService.getCliente(tipoDocumento, nroDocumento);
    }
}
@WebMvcTest(controllers = ClienteController.class)
@ActiveProfiles("test")
@Import({CircuitBreakerConfiguration.class,
    RetryConfiguration.class,
    RateLimiterConfiguration.class,
    SecurityConfig.class})
public class ClienteControllerTests {
    @Autowired
    MockMvc mockMvc;
    @MockBean
    ClienteService clienteService;
    @Autowired
    ObjectMapper objectMapper;

    private ClienteModel crearClienteModelValido() {...}

    @Test
    public void pasaRequestCorrecta() throws Exception {
        //dado
        when(clienteService.getCliente(anyInt(), anyInt())).thenReturn(crearClienteModelValido());

        //entonces
        String response = mockMvc.perform(get("/api/v1/clientes")
                .param("tipoDocumento", "0")
                .param("nroDocumento", "10000000")
                .with(httpBasic("admin", "password"))
            )
            .andExpect(status().isOk())
            .andReturn()
            .getResponse()
            .getContentAsString();

        ClienteModel cliente = objectMapper.readValue(response, ClienteModel.class);
        //...
    }
}

这一切都始于我检查MockHttpServletResponse中的Body只是空的,而它应该有一个对象。然后,在调试时,我注意到测试和控制器中的clienteService是一个真实的示例,而不是一个mock(据我所知):clienteService = {ClienteService@8607}。这意味着when(...).thenReturn(...)什么也不做,这解释了后面的空响应。
所以我不知道该怎么办,我已经检查了与此相关的各种帖子,但没有解决我的问题。不过,想想看,我记得我第一次开始测试这个应用程序时的一些事情。我只做@SpringBootTest(s),所以我只使用@Autowired@MockBean。在那个场合,我记得在使用@Autowired时遇到了麻烦,因为它似乎不能正确地自动连接东西。我记得出于某种原因,我通过显式地将JUnit 4添加到pom.xml来解决这个问题。我最近删除了它,因为我正在从头开始重做测试,这似乎是不必要的,但也许这与它有关?
注意:CircuitBreakerRegistry也是一个真实的示例(请看控制器)。但我并不感到惊讶,因为我没有嘲笑它。

z0qdvdin

z0qdvdin1#

我相信你是在注射假的否则,这行when(clienteService.getCliente(anyInt(), anyInt())).thenReturn(crearClienteModelValido());将抛出异常。
我怀疑您没有看到所需的行为,因为您的匹配器与参数类型不匹配。
您的匹配器表明您正在使用(int, int)调用此方法,但您正在使用(int, long)调用它。
修改你的mock函数以反映你传递的参数类型,你应该做得很好。

when(clienteService.getCliente(anyInt(), anyLong())).thenReturn(crearClienteModelValido());

相关问题