Rest Assured doesn't use custom ObjectMapper

2019-05-15 08:13发布

I'm making Controller tests for my Spring Boot project using Rest Assured. We are using Java 8 ZonedDateTime fields on our serialized objects and Jackson 2 for our serialization. When running the project, serialization works as expected, but when running Rest Assured tests, the dates are not serializing correctly. I understand that Rest Assured uses its own ObjectMapper config, but my problem is that no matter what I do, Rest Assured appears to be ignoring my ObjectMapper configuration.

Here are the relevant parts of my test:

@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;
}

We're using spring-boot-starter-data-jpa, so we just declared an ItemRepository interface that extends CrudRepository(Item, Long) (I just used parenthesis here because stack overflow didn't like the angle brackets) and the controller calls the service which calls the built in save method to persist the Item and returns the persisted Item, so in my test, I'm expecting the date I sent in to be saved to be the same when it's returned.

The main problem I'm having is that the returned date is in GMT, whereas my expectation is that it'll be in EST/EDT, and thus the assertion fails because ZonedDateTime.now() uses the local time zone, but for whatever reason, Rest Assured is, somewhere along the line, changing the time zone to 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]>

There's also one date that's not even getting serialized as an ISO, but as a weird decimal. No idea what's up with that one, but it doesn't happen when the project is running; neither of these problems do. It's only when Rest Assured tests are run.

I'm getting this error no matter what I configure the ObjectMapper to be in my test setUp... Regardless of whether I even HAVE an ObjectMapper there or not, it's getting completely ignored.

Relevant technology versions:

  • 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条回答
姐就是有狂的资本
2楼-- · 2019-05-15 08:23

You shouldn't use RestAssured.config and RestAssuredConfig when using RestAssured with MockMvc. Instead use io.restassured.module.mockmvc.RestAssuredMockMvc and io.restassured.module.mockmvc.config.RestAssuredMockMvcConfig. I.e. replace your code:

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

with:

RestAssuredMockMvc.config = RestAssuredConfigMockMvc.config().objectMapperConfig(
    ...
);
查看更多
登录 后发表回答