Spring MVC 测试,MockMVC:方便地将对象与 JSON 进行转换

Posted

技术标签:

【中文标题】Spring MVC 测试,MockMVC:方便地将对象与 JSON 进行转换【英文标题】:Spring MVC Test, MockMVC: Conveniently convert objects to/from JSON 【发布时间】:2016-11-22 03:37:11 【问题描述】:

我已经习惯了 JAX-RS,并且希望在使用 Spring MVC 发送请求并处理响应时也能获得类似的舒适感,即在我的测试中的客户端。

在服务器(控制器)端,我对自动转换非常满意,即只需返回一个对象实例并将生成的 HTTP 响应中的 JSON 发送到客户端就足够了。

您能告诉我如何解决在这些 sn-ps 中将 objectInstance 转换为 jsonString 或反之亦然的手动过程吗?如果可能,我也想跳过手动配置内容类型。

String jsonStringRequest = objectMapper.writeValueAsString(objectInstance);

ResultActions resultActions = mockMvc.perform(post(PATH)
    .contentType(MediaType.APPLICATION_JSON)
    .content(jsonStringRequest)
)

String jsonStringResponse = resultActions.andReturn().getResponse().getContentAsString();
Some objectInstanceResponse = objectMapper.readValue(jsonStringResponse, Some.class);

作为比较,使用 JAX-RS 客户端 API,我可以轻松地使用 request.post(Entity.entity(objectInstance, MediaType.APPLICATION_JSON_TYPE) 发送对象并使用 response.readEntity(Some.class); 读取响应

【问题讨论】:

【参考方案1】:

如果你有很多响应对象,你可以创建一些通用的 JsonToObject 映射器工厂。然后可以使用它从通用响应中检测对象类型(所有响应对象都继承自同一个通用类),并从错误的映射尝试中正确响应/记录。

我手头没有代码示例,但作为伪代码:

public abstract GenericResponse 
  public String responseClassName = null;
  // get/set

在服务器代码中,将实际响应对象的名称添加到此类。

JsonToObject 工厂

public ConverterFactory<T> 
   private T objectType;
   public ConverterFactory(T type) 
     objectType = type;
   

  public T convert(String jsonString) 
    // Type check
    GenericResponse genResp = mapper.readValue(result.getResponse().getContentAsString(),
            GenericResponse.class);
    if (objectType.getClass().getSimpleName().equals(genResp.getResponseClassName())) 
      // ObjectMapper code
      return mapper.readValue(result.getResponse().getContentAsString(),
            objectType.class);
     else 
      // Error handling
    
  

我认为这可以扩展为与注释一起使用,以对响应进行更多自动化魔术。 (开始检查 BeanPostProcessor)

@Component
public class AnnotationWorker implements BeanPostProcessor 

  @Override
  public Object postProcessBeforeInitialization(final Object bean, String name) throws BeansException 
    ReflectionUtils.doWithFields(bean.getClass(), field -> 
        // make the field accessible if defined private
        ReflectionUtils.makeAccessible(field);
        if (field.getAnnotation(MyAnnotation.class) != null) 
            field.set(bean, log);
        
    );
    return bean;
  

上面的代码 sn-p 是从我当前的项目中复制的,它注入到字段中,您需要对其进行更改,使其适用于方法,例如......您可能需要它的地方。

实现这一切可能会很棘手,甚至不能说它一定有效,但如果您不介意一些教育工作,那么可以尝试一下。

【讨论】:

以上是关于Spring MVC 测试,MockMVC:方便地将对象与 JSON 进行转换的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 1.4 MVC 测试中使用 @WebMvcTest 设置 MockMvc

Spring Boot RestApi 测试教程 Mock 的使用

模拟 MVC - 添加请求参数进行测试

Spring MVC 与 Spring Security 的集成测试

Spring4 Spring MVC实战——MockMvc报org.springframework.core.CollectionFactory.createLinkedMap错误

Spring MVC 测试中的空异常体