gpt4 book ai didi

spring-boot - 如何在@WebMvcTest 的服务层上模拟 beans Autowired

转载 作者:行者123 更新时间:2023-11-28 21:36:46 24 4
gpt4 key购买 nike

我正在 Spring boot gradle 应用程序中测试 REST API,我使用 @MockBean 的模拟服务返回 null。如果服务类中有一些 Autowiring 的 bean(我使用了构造函数注入(inject)),则此模拟服务返回 null。

示例代码(未编译,仅供理解)


@RestController
@RequestMapping("/xxx")
class TestController {

private RetriveDataService retriveDataService;

public TestControllerx(RetriveDataService retriveDataService) {
this.retriveDataService = retriveDataService;
}

@PostMapping(value = "/yyy")
public MyResponseModel myMethod(@RequestBody MyRequestModel model) {

return retriveDataService.retriveData(model);
}

}

@Service
class RetriveDataService {

private TokenService tokenService;

public RetriveDataService(TokenService tokenService) {
this.tokenService = tokenService;
}

public MyResponseModel retriveData(MyRequestModel model) {
String accessToken = tokenService.getToken().getAccessToken();

return retriveData(model, accessToken);
}

}

@RunWith(SpringRunner.class)
@WebMvcTest(TestController.class)
public class TestControllerTest {

@Autowired
private MockMvc mvc;

@Autowired
private ObjectMapper objectMapper;

@MockBean
private RetriveDataService retriveDataService;

@Test
public void testRetriveData() throws Exception {

mvc.perform(MockMvcRequestBuilders.post("/xxx/yyy").content(objectMapper.writeValueAsString(new MyRequestModel()))
.contentType(MediaType.APPLICATION_JSON_UTF8)).andDo(MockMvcResultHandlers.print())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8));
}

}

当我运行这个测试时,我得到以下输出(如果我的服务不需要另一个 bean,我得到预期的输出)

MockHttpServletResponse:
Status = 200
Error message = null
Headers = []
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []

由于这个响应,我在 .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)); 线上遇到了问题。当我检查响应正文时(因为正文也是空的)

重现问题的示例项目是 here

最佳答案

检查您的存储库确认假设形成问题评论中的讨论。

您在模拟中指定期望值

MyModel requestMessage = new MyModel();
requestMessage.setMessage("Hello Request Post");
given(testService1.getMessage(requestMessage)).willReturn(responseMessage);

但在您的 @WebMvcTest 中您的 Controller 中收到的消息不等于测试中指定的 requestMessage。这是因为 MyModel 类没有覆盖 equals 方法。在这种情况下,Mockito 将使用其默认行为:

By default, for all methods that return a value, a mock will return either null, a primitive/primitive wrapper value, or an empty collection, as appropriate. For example 0 for an int/Integer and false for a boolean/Boolean.

您有两种选择来解决问题:

  1. 在您的请求类中覆盖equals(和hashCode)。
  2. 熟悉参数匹配器

关于选项 2 的更多信息:

从技术上讲,您的期望等同于:

given(testService1.getMessage(ArgumentMatchers.eq(requestMessage)))
.willReturn(responseMessage);

您可以使用其他匹配器,甚至可以定义您自己的匹配器。如果您不能修改参数类型的代码(来自 3-rd 方库等的类型),这将很有用。例如,您可以使用 ArgumentMatchers.any(MyModel.class))

关于spring-boot - 如何在@WebMvcTest 的服务层上模拟 beans Autowired,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57968361/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com