spring restdocs webtestclient忽略自定义jackson模块

时间:2018-06-13 02:44:20

标签: spring-restdocs

我的系统

  • spring-boot-version "dependencies": { "@material-ui/core": "^1.1.0", "axios": "^0.18.0", "immutability-helper": "^2.7.0", "react": "^16.3.2", "react-dom": "^16.3.2", "react-redux": "^5.0.7", "react-router-dom": "^4.2.2", "react-scripts": "1.1.4", "styled-components": "^3.3.0" },
  • spring-Cloud-Version 2.0.1.RELEASE
  • java 1.8
  • org.springframework.boot:弹簧引导起动webflux
  • org.javamoney:莫尼塔:1.2.1
  • org.springframework.restdocs:spring-restdocs-webtestclient

自定义SimpleModule

Finchley.M9

集成测试

  @Bean
  public SimpleModule moneyModule() {
    return new MoneyModule();
  }

  public MoneyModule() {
      addSerializer(Money.class, new MoneySerializer());
      addValueInstantiator(Money.class, new MoneyInstantiator());
  }

测试错误

@RunWith(SpringRunner.class)
@ActiveProfiles("integTest")
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class XxxxHandlerTest{
    @Autowired
  WebTestClient webTestClient;

  @Rule
  public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

  @Autowired
  ApplicationContext context;

  @Before
  public void init() throws Exception {
    this.webTestClient = WebTestClient.bindToApplicationContext(this.context)
        .configureClient()
        .baseUrl("http://local.com.cn")
        .filter(WebTestClientRestDocumentation
            .documentationConfiguration(this.restDocumentation)
            .operationPreprocessors()
            .withResponseDefaults(prettyPrint())
        )
        .build();
  }

  @Test
  public void testStoreVoucher() {
    Operator mockUser = Operator.builder().name("jack").id(ObjectId.get().toString()).build();
    List<AccountingEntry> accountingEntries = Arrays.asList(AccountingEntry.builder()
        .code("12121").summary("receipt").debit(Money.of(100, "CNY"))
        .credit(Money.of(100, "CNY")).build());
    VoucherPost voucherPost = VoucherPost.builder().operator(mockUser)
        .accountingEntries(accountingEntries).build();
    webTestClient.post()
        .uri(mockUrl)
        .body(BodyInserters.fromObject(voucherPost))
        .exchange().expectStatus().isOk();
}

当我删除以下代码时,测试代码正常运行

org.springframework.core.codec.DecodingException: JSON decoding error: Cannot construct instance of `org.javamoney.moneta.Money` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.javamoney.moneta.Money` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)

我猜webtestclient的配置导致它忽略了自定义jackson模块,所以我想知道如何解决这个问题。也许没有任何问题,但我的配置是错误的。请给我一些建议。谢谢。

1 个答案:

答案 0 :(得分:0)

当您使用Spring Boot时,我建议您使用@AutoConfigureRestDocs而不是手动配置WebTestClient以使用REST文档。这是使用自定义模块杰克逊WebTestClient配置ObjectMapper的最简单方法。

为此,您的测试类看起来像这样:

@RunWith(SpringRunner.class)
@ActiveProfiles("integTest")
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureRestDocs(uriHost="local.com.cn")
public class XxxxHandlerTest{

    @Autowired
    WebTestClient webTestClient;

    @Test
    public void testStoreVoucher() {
        Operator mockUser = Operator.builder().name("jack").id(ObjectId.get().toString()).build();
        List<AccountingEntry> accountingEntries = Arrays.asList(AccountingEntry.builder()
            .code("12121").summary("receipt").debit(Money.of(100, "CNY"))
            .credit(Money.of(100, "CNY")).build());
        VoucherPost voucherPost = VoucherPost.builder().operator(mockUser)
            .accountingEntries(accountingEntries).build();
        webTestClient.post()
            .uri(mockUrl)
            .body(BodyInserters.fromObject(voucherPost))
            .exchange().expectStatus().isOk();
    }

}