当@PathVariable是字符串时,Spring控制器测试失败,返回404。
当@PathVariable是字符串时,Spring控制器测试失败,返回404。
我正在尝试测试一个Spring控制器方法 - 该方法在帖子末尾,下面是测试类。我已经把它简化了一点,以便更好地缩小问题的范围。
当我按原样运行测试时,它会失败:
java.lang.AssertionError: Status Expected :200 Actual :404
如果我将mockMvc.perform编辑为如下内容,则测试通过,我甚至不必更改控制器中的@PathVariables为Longs:
mockMvc.perform(get(ApplicationEndPoints.GET_CCS_NAME_AND_ADDRESS_AJAX, 1L, 2L)) .andExpect(status().isOk());
控制器方法本身工作正常并返回JSON,如预期。我可以只使用这些Long值并期望测试OK,还是如何通过字符串使其工作?
我应该补充说,我完全不了解测试。谢谢!
控制器方法:
@PreAuthorize("hasAuthority('auditor')") @RequestMapping(value = ApplicationEndPoints.GET_APPLICANT_DATA, method = RequestMethod.GET) @ResponseBody public ApplicantData getNameAndAddress(@PathVariable("businessId") String businessId, @PathVariable("date") String date) { //Date d = Date.valueOf(date); ApplicantParams params = new ApplicantParams(); //params.setBusinessId(businessId); //params.setApplicationReceivedDate(d); params.setRoleId(ADDRESS_ROLE.HR.getRoleId()); return applicantService.getApplicantData(params); }
测试类:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {ApplicationTestConfig.class}) @WebAppConfiguration public class ClientDetailAjaxControllerTest { @InjectMocks private ClientDetailAjaxController clientDetailAjaxController; private MockMvc mockMvc; private ApplicantServiceInterface applicantService = Mockito.mock(ApplicantServiceImpl.class, Mockito.RETURNS_DEEP_STUBS); @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mockMvc = MockMvcBuilders.standaloneSetup(clientDetailAjaxController).build(); } @Test public void getNameAndAddress() throws Exception { Mockito.when(applicantService.getApplicantData(Mockito.any(ApplicantParams.class))) .thenReturn(ApplicationTestData.getApplicantData()); mockMvc.perform(get(ApplicationEndPoints.GET_APPLICANT_DATA, Mockito.anyString(), Mockito.anyString())) .andExpect(status().isOk()); Mockito.verify(applicantService, Mockito.times(1)).getApplicantData(Mockito.any(ApplicantParams.class)); Mockito.verifyNoMoreInteractions(applicantService); } }
编辑:我已经根据评论对一些事情进行了澄清...
admin 更改状态以发布 2023年5月20日
404告诉你,mockMVC无法匹配你要调用的控制器方法。
我注意到,在你的控制器中,路径是ApplicationEndPoints.GET_APPLICANT_DATA
,而在你展示的测试中,路径是ApplicationEndPoints.GET_CCS_NAME_AND_ADDRESS_AJAX
。
尽管如此-不要在mockMVC perform
方法中使用Mockito.anyString()
来替代你必须提供给你的RequestBuilder
的参数值。
下面是一个代码样例:
要测试这个控制器方法:
@RequestMapping(value = "/applicant/name-and-address/", method = RequestMethod.GET) public ApplicantData getNameAndAddress(@PathVariable("businessId") String businessId, @PathVariable("date") String date) { // some code }
你需要做的是:
mockMvc.perform(get("/applicant/name-and-address/{businessId}/{date}", "myBusinessId", "myDateAsString")).andExpect(status().isOk());
区别在于你必须传递实际的字符串值,而不是Mockito.anyString()。
其他注意事项:
-
如果你的URL路径变量和你绑定它的参数名称相同,你可以写
@PathVariable String id
,而不是@PathVariable("id") String id
。 -
你可以使用
@GetMapping
代替@RequestMapping
来处理GET
方法,使用@PostMapping
来处理POST
等。