所以我在
@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
也是一个真实的实例(看控制器)。但这并不令我惊讶,因为我并不是在嘲笑它。
我相信你正在注入模拟;否则,这条线
when(clienteService.getCliente(anyInt(), anyInt())).thenReturn(crearClienteModelValido());
会抛出异常。
我怀疑您没有看到所需的行为,因为您的匹配器与参数类型不匹配。
您的匹配器表明您正在使用
(int, int)
调用此方法,但您正在使用 (int, long)
调用它。
更改你的模拟存根以反映你正在传递的参数类型,你应该很好。
when(clienteService.getCliente(anyInt(), anyLong())).thenReturn(crearClienteModelValido());