Rest Assured 不使用自定义 ObjectMapper

Posted

技术标签:

【中文标题】Rest Assured 不使用自定义 ObjectMapper【英文标题】:Rest Assured doesn't use custom ObjectMapper 【发布时间】:2017-08-24 22:43:01 【问题描述】:

我正在使用 Rest Assured 为我的 Spring Boot 项目进行控制器测试。我们在序列化对象上使用 Java 8 ZonedDateTime 字段,在序列化对象上使用 Jackson 2。运行项目时,序列化按预期工作,但运行 Rest Assured 测试时,日期序列化不正确。我了解 Rest Assured 使用自己的 ObjectMapper 配置,但我的问题是,无论我做什么,Rest Assured 似乎都忽略了我的 ObjectMapper 配置。

以下是我测试的相关部分:

@RunWith(SpringRunner.class)
@SpringBootTest(classes=MyApplication.class)
@WebAppConfiguration
@Transactional
public class MAppControllerTest 

    @Autowired
    private WebApplicationContext context;

    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception 

        RestAssured.config = RestAssuredConfig.config().objectMapperConfig(
              ObjectMapperConfig.objectMapperConfig().jackson2ObjectMapperFactory(new Jackson2ObjectMapperFactory() 
                  @SuppressWarnings("rawtypes") 
                  @Override 
                  public ObjectMapper create(Class cls, String charset)  
                    ObjectMapper objectMapper = new ObjectMapper(); 
                    objectMapper.registerModule(new JavaTimeModule()); 
                    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); 
                    objectMapper.setTimeZone(TimeZone.getTimeZone("America/New_York"));
                    objectMapperconfigure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, true);
                    return objectMapper; 
                   
            )
         );

        mockMvc = MockMvcBuilders.webAppContextSetup(context)
            .apply(springSecurity())
            .build();
    

    @Test
    @WithMockUser(roles = "APP_ADMIN", username = "TEST_USER")
    @Sql(scripts = "/db-scripts/test-data.sql")
    public void testCreateItem() 
        Item postBody = new Item();
        postBody.setDate(ZonedDateTime.now());

        Item result =
        given().
            mockMvc(mockMvc).
            contentType(ContentType.JSON).
            body(postBody).
            log().all().
        when().
            post("/items").
        then().
            log().all().
            statusCode(201).
            body(matchesJsonSchemaInClasspath("json-schemas/item.json")).
            extract().as(Item.class);

        assertThat(result.getDate(), equalTo(postBody.getDate());
    

Item.class:

@Data
@Entity
@Table(name = "ITEM", schema = "MY_APP")
@EqualsAndHashCode(of = "id")
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Item implements Serializable 

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ITEM_ID_SEQ")
    @SequenceGenerator(name = "ITEM_ID_SEQ", sequenceName = "MY_APP.ITEM_ID_SEQ")
    private Long id;

    @Column(name = "DATE")
    private ZonedDateTime date;

我们使用的是 spring-boot-starter-data-jpa,所以我们只是声明了一个扩展 CrudRepository(Item, Long) 的 ItemRepository 接口(我在这里只使用了括号,因为堆栈溢出不喜欢尖括号)和控制器调用调用内置保存方法的服务来持久化项目并返回持久化的项目,所以在我的测试中,我希望我发送的日期在返回时被保存。

我遇到的主要问题是返回的日期是格林威治标准时间,而我的期望是它将在美国东部标准时间/美国东部时间,因此断言失败,因为 ZonedDateTime.now() 使用本地时区,但无论出于何种原因,Rest Assured 都会将时区更改为 GMT:

java.lang.AssertionError:
Expected: <2017-03-30T14:53:19.102-04:00[America/New_York]>
but: was <2017-03-30T18:53:19.102Z[GMT]>

还有一个日期甚至没有被序列化为 ISO,而是作为一个奇怪的小数。不知道那是怎么回事,但是在项目运行时不会发生;这些问题都没有。仅在运行 Rest Assured 测试时。

无论我将 ObjectMapper 配置为在我的测试集中如何,我都会收到此错误...无论我是否有一个 ObjectMapper,它都会被完全忽略。

相关技术版本:

Spring Boot:1.5.2.RELEASE com.fasterxml.jackson.core:jackson-databind: 2.6.4 com.fasterxml.jackson.core:jackson-annotations: 2.6.4 com.fasterxml.jackson.core:jackson-core: 2.6.4 com.fasterxml.jackson.datatype:jackson-datatype-jsr310: 2.6.4 com.jayway.restassured:rest-assured: 2.9.0 com.jayway.restassured:json-schema-validator: 2.9.0 com.jayway.restassured:spring-mock-mvc: 2.9.0

【问题讨论】:

【参考方案1】:

在将 RestAssured 与 MockMvc 一起使用时,您不应使用 RestAssured.configRestAssuredConfig。而是使用io.restassured.module.mockmvc.RestAssuredMockMvcio.restassured.module.mockmvc.config.RestAssuredMockMvcConfig。 IE。替换你的代码:

RestAssured.config = RestAssuredConfig.config().objectMapperConfig(
   ...
);

与:

RestAssuredMockMvc.config = RestAssuredConfigMockMvc.config().objectMapperConfig(
    ...
);

【讨论】:

如果我使用它也会起作用吗: RestAssuredMockMvc.standaloneSetup(...) ?

以上是关于Rest Assured 不使用自定义 ObjectMapper的主要内容,如果未能解决你的问题,请参考以下文章

rest-assured的日志使用介绍

Rest Assured:发出请求返回错误“JSON输入文本既不应为null也不应为空”。

使用 REST Assured 进行测试时出现 java.lang.AbstractMethodError

Rest-Assured表单身份验证不起作用

是否可以使用 Java Stream api 重写带有 Rest-Assured 请求尝试的 WHILE 循环

Rest-Assured api 是不是支持 SOAP