服务的@MockBean返回真实实例而不是@WebMvcTest(s)中的模拟

问题描述 投票:0回答:1

所以我在

@WebMvcTest
下进行测试,我刚刚注意到使用我的控制器使用的服务的
@MockBean
进行的模拟不起作用。老实说,我不知道该怎么办。我正在使用 Spring 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
是真实实例而不是模拟(据我所知):
clienteService = {ClienteService@8607}
。这意味着
when(...).thenReturn(...)
没有执行任何操作,这解释了稍后的空响应。

所以我不知道该怎么办,我检查了与此相关的各种帖子,但没有一个能解决我的问题。不过,仔细想想,我想起了我第一次开始测试该应用程序时的一些事情。我只做

@SpringBootTest
,所以我只使用
@Autowired
@MockBean
。在那种情况下,我记得
@Autowired
遇到了麻烦,因为它似乎无法正确地自动连接事物。我记得由于某种原因,通过在 pom.xml 中明确添加
JUnit 4
来解决这个问题。我最近删除了它,因为我正在从头开始重做测试,这似乎没有必要,但也许它与它有关?

注意:

CircuitBreakerRegistry
也是一个真实的实例(看控制器)。但这并不令我惊讶,因为我并不是在嘲笑它。

spring spring-boot testing controller mockito
1个回答
0
投票

我相信你正在注入模拟;否则,这条线

when(clienteService.getCliente(anyInt(), anyInt())).thenReturn(crearClienteModelValido());
会抛出异常。

我怀疑您没有看到所需的行为,因为您的匹配器与参数类型不匹配。

您的匹配器表明您正在使用

(int, int)
调用此方法,但您正在使用
(int, long)
调用它。

更改你的模拟存根以反映你正在传递的参数类型,你应该很好。

when(clienteService.getCliente(anyInt(), anyLong())).thenReturn(crearClienteModelValido());
© www.soinside.com 2019 - 2024. All rights reserved.