我正在使用Rest Assured为我的Spring Boot项目进行Controller测试。我们在序列化对象上使用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接口(我在这里使用括号是因为堆栈溢出不喜欢尖括号)和控制器调用该服务调用了内置的save方法以持久保存Item并返回持久的Item,因此在我的测试中,我希望返回的发送日期保持不变。

我遇到的主要问题是返回的日期是格林尼治标准时间,而我的期望是它将在EST / EDT中,因此断言失败是因为ZonedDateTime.now()使用本地时区,但无论如何原因是“放心”是将时区更改为格林尼治标准时间:

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,而是一个奇怪的十进制。不知道那是怎么回事,但是在项目运行时不会发生。这些问题都没有。仅在运行“确保放心”测试时。

无论我将ObjectMapper配置在测试设置中是什么,我都会遇到此错误...无论我是否在那里有ObjectMapper,它都将被完全忽略。

相关技术版本:


春季靴:1.5.2。发布
com.fasterxml.jackson.core:jackson-databind:2.6.4
com.fasterxml.jackson.core:jackson注释: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:保证放心:2.9.0
com.jayway.restassured:json-schema-validator:2.9.0
com.jayway.restassured:spring-mock-mvc:2.9.0

最佳答案

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

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


与:

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

10-07 19:45
查看更多