繁体   English   中英

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

[英]Spring MVC Test, MockMVC: Conveniently convert objects to/from JSON

我已经习惯了JAX-RS,并希望在使用Spring MVC发送请求并使用响应时(即在测试内部的客户端)具有类似的舒适度。

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

你能告诉我如何解决转换的手工工艺objectInstancejsonString在这些片段或反之亦然? 如果可能的话,我也想跳过手动配置内容类型的步骤。

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)发送对象request.post(Entity.entity(objectInstance, MediaType.APPLICATION_JSON_TYPE)并使用response.readEntity(Some.class);读取响应response.readEntity(Some.class);

如果您有很多响应对象,则可以创建一些通用的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;
  }
}

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

实施所有这些可能很棘手,甚至不能说它一定能奏效,但是如果您不介意进行一些教育性工作,则可以尝试一下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM