【问题标题】:RestAssured does not respect ObjectMapper configuration in QuarkusRestAssured 不尊重 Quarkus 中的 ObjectMapper 配置
【发布时间】:2020-03-06 18:10:50
【问题描述】:

我对我的 Quarkus 应用程序中的 ObjectMapper 配置进行了非常简单的调整,如 Quarkus 指南所述:

@Singleton
public class ObjectMapperConfig implements ObjectMapperCustomizer {

    @Override
    public void customize(ObjectMapper objectMapper) {
        objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
        objectMapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
        objectMapper.registerModule(new JavaTimeModule());
    }

}

我这样做是为了使用 @JsonRootName 注释来包装/解开我的对象:

@RegisterForReflection
@JsonRootName("article")
public class CreateArticleRequest {

    private CreateArticleRequest(String title, String description, String body, List<String> tagList) {
        this.title = title;
        this.description = description;
        this.body = body;
        this.tagList = tagList;
    }

    private String title;
    private String description;
    private String body;
    private List<String> tagList;

    ... 

}

curl 针对我的实际 API 时,这工作得很好,但是每当我在我的一个测试中使用 RestAssured 时,RestAssured 似乎不尊重我的 ObjectMapper 配置,并且不包装 CreateArticleRequest,因为它应该按照指示做通过@JsonRootName 注释。

@QuarkusTest
public class ArticleResourceTest {

    @Test
    public void testCreateArticle() {
        given()
            .when()
            .body(CREATE_ARTICLE_REQUEST)
            .contentType(ContentType.JSON)
            .log().all()
            .post("/api/articles")
            .then()
            .statusCode(201)
            .body("", equalTo(""))
            .body("article.title", equalTo(ARTICLE_TITLE))
            .body("article.favorited", equalTo(ARTICLE_FAVORITE))
            .body("article.body", equalTo(ARTICLE_BODY))
            .body("article.favoritesCount", equalTo(ARTICLE_FAVORITE_COUNT))
            .body("article.taglist", equalTo(ARTICLE_TAG_LIST));
    }

}

这将我的请求正文序列化为:

{
    "title": "How to train your dragon",
    "description": "Ever wonder how?",
    "body": "Very carefully.",
    "tagList": [
        "dragons",
        "training"
    ]
}

...而不是...

{
    "article": {
        "title": "How to train your dragon",
        "description": "Ever wonder how?",
        "body": "Very carefully.",
        "tagList": [
            "dragons",
            "training"
        ]
    }
}

我实际上可以通过手动配置 RestAssured ObjectMapper 来解决这个问题,如下所示:

@QuarkusTest
public class ArticleResourceTest {

    @BeforeEach
    void setUp() {
        RestAssured.config = RestAssuredConfig.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory(
            (cls, charset) -> {
                ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
                mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
                mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
                mapper.registerModule(new JavaTimeModule());
                return mapper;
            }
        ));
    }
}

但是,我显然不想这样做!我希望 RestAssured 获取我的 ObjectMapper 配置,这样我就不需要保留两个不同的 ObjectMapper 配置。

为什么没有收到?我错过了什么?

【问题讨论】:

  • 这是一个很好的功能请求恕我直言!能否请您打开一个问题并 ping 我(github 上的@geoand)?
  • 我已经有了这个工作的原型。只是需要一些清理。一旦我在 Github 上打开拉取请求,我就会回帖。
  • 添加该功能的 PR 已打开:github.com/quarkusio/quarkus/pull/5430

标签: java rest-assured objectmapper quarkus


【解决方案1】:

所以实际上 Quarkus 不会自动执行此操作(因为它会干扰原生测试)。

但是你可以使用:

@Inject
ObjectMapper

在测试内部设置RestAssured.config

【讨论】:

    【解决方案2】:

    只是为了更新,以防有人发现像我这样......

    我只是添加了 Singleton ObjectMapperConfig,这正在运行

    <quarkus.platform.version>2.3.0.Final</quarkus.platform.version>
    
        <dependency>
          <groupId>io.rest-assured</groupId>
          <artifactId>rest-assured</artifactId>
          <scope>test</scope>
        </dependency>
    

    【讨论】:

      【解决方案3】:

      我解决了这个问题

      @QuarkusTest
      public class RESTResourceTest {
      
          @Inject
          ObjectMapper mapper;
      
          @BeforeEach
          void setUp() {
              RestAssured.config = RestAssured.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory( (cls, charset) -> mapper ));
          }
      

      在我的 src/main/java 的其他地方我有我的自定义 ObjectMapper 定制器:

      import javax.inject.Singleton;
      
      import com.fasterxml.jackson.databind.ObjectMapper;
      
      import io.cloudevents.jackson.JsonFormat;
      import io.quarkus.jackson.ObjectMapperCustomizer;
      
      @Singleton
      public class QuarkusObjectMapperCustomizer implements ObjectMapperCustomizer {
      
          public void customize(ObjectMapper mapper) {
              mapper.registerModule(JsonFormat.getCloudEventJacksonModule());
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-05
        • 2019-03-10
        • 1970-01-01
        • 2018-05-28
        • 2013-10-01
        • 1970-01-01
        • 2017-12-10
        • 2019-08-26
        • 1970-01-01
        相关资源
        最近更新 更多