我正在使用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,它都会被完全忽略。
相关技术版本:
答案 0 :(得分:1)
使用RestAssured和MockMvc时,不应使用RestAssured.config
和RestAssuredConfig
。而是使用io.restassured.module.mockmvc.RestAssuredMockMvc
和io.restassured.module.mockmvc.config.RestAssuredMockMvcConfig
。即替换你的代码:
RestAssured.config = RestAssuredConfig.config().objectMapperConfig(
...
);
使用:
RestAssuredMockMvc.config = RestAssuredConfigMockMvc.config().objectMapperConfig(
...
);