我正在尝试为控制器中定义的方法编写单元测试代码。 方法是这样的:
@RestController
@RequestMapping("/products")
public class RestProductController {
@RequestMapping(value="/{product}/skus", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public List<SkuSummaryVO> getSkuByProduct(@Valid @PathVariable Product product){
List<SkuSummaryVO> skusByProductVOs = skuService.getSkusByProduct(product);
return skusByProductVOs;
}
}
我们在Configuration类中使用注释@EnableSpringDataWebSupport来启用DomainClassConverter功能。因此我们可以将JPA实体用作@PathVariable。因此,当在URL中设置产品ID时,我们将获得产品(在场景后面有请求)。
我们正在开发单元测试而不启用Spring App Context并使用Mockito。 所以我们像这样初始化mockMvcBuilders:
public class RestProductControllerTest {
...
@Before
public void setUp() {
RestProductController restProductController = new RestProductController();
...
mockMvc = MockMvcBuilders.standaloneSetup(restProductController).build();
}
}
,测试方法如下:
@Test
public void testGetProductById() throws Exception {
...
String jsonResult = ...;
mockMvc.perform(get("/products/123/skus").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(content().string(jsonResult));
}
我获得了HttpCode的500(状态)
单元测试对于没有使用DomainClassConverter功能的控制器方法工作正常(例如,如果我使用Long productId
而不是Product product
作为getSkuByProduct
的参数,它会工作)
答案 0 :(得分:2)
更新:第二个想法,我最初提出的内容永远无法工作,因为DomainClassConverter
要求您的Spring数据存储库出现在ApplicationContext
中,并且在您的示例中您正在使用永远不会创建包含Spring数据存储库的StandaloneMockMvcBuilder
的{{1}}。
我看到它的方式,你有两种选择。
ApplicationContext
(通过ApplicationContext
加载,如参考手册中所示)将测试转换为集成测试,并将其传递给@ContextConfiguration
。如果配置的MockMvcBuilders.webAppContextSetup(WebApplicationContext)
包含您的Spring Data Web配置,那么您应该很高兴。ApplicationContext
,而是通过DomainClassConverter
设置自定义HandlerMethodArgumentResolver
(例如,存根或模拟)。然后,您的自定义解析程序可以返回您想要的任何StandaloneMockMvcBuilder.setCustomArgumentResolvers(HandlerMethodArgumentResolver...)
实例。您必须在调用Product
时创建的DomainClassConverter
中注册ConversionService
的{{1}}实例。
在StandaloneMockMvcBuilder
中,您可以看到MockMvcBuilders.standaloneSetup(Object...)
被实例化(并间接注册),如下所示:
SpringDataWebConfiguration.registerDomainClassConverterFor()
您可以通过DomainClassConverter
设置自己的DomainClassConverter<FormattingConversionService> converter =
new DomainClassConverter<FormattingConversionService>(conversionService);
converter.setApplicationContext(context);
。有关如何为Web环境配置FormattingConversionService
的示例,请参阅StandaloneMockMvcBuilder.setConversionService()
。
接下来的挑战是如何获得对WebMvcConfigurationSupport.mvcConversionService()
的引用。在内部,ConversionService
使用ApplicationContext
,但据我所知(在Spring 4.1之前),没有子类化StandaloneMockMvcBuilder
就无法直接访问它。
从Spring Framework 4.1开始,您可以实现自定义StubWebApplicationContext
(通过其StandaloneMockMvcBuilder
方法,您可以访问MockMvcConfigurer
。
希望有足够的信息让你走上正轨!
祝你好运......萨姆
答案 1 :(得分:0)
您可以通过WebConversionService
模拟从字符串到实体的转换。查看this答案以获取一些代码示例和更多详细信息。