Rest Assured不使用自定义ObjectMapper

时间:2017-03-30 20:11:53

标签: spring-boot java-8 jackson timezone rest-assured

我正在使用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,所以在我的测试中,我希望我发送的日期保存在返回时是相同的。

我遇到的主要问题是返回的日期是GMT,而我的期望是它将在EST / EDT中,因此断言失败,因为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配置在我的测试setUp中,我都会收到此错误...无论我是否还有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 个答案:

答案 0 :(得分:1)

使用RestAssured和MockMvc时,不应使用RestAssured.configRestAssuredConfig。而是使用io.restassured.module.mockmvc.RestAssuredMockMvcio.restassured.module.mockmvc.config.RestAssuredMockMvcConfig。即替换你的代码:

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

使用:

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