Browse Source

Polishing Jackson encoder tests

pull/27953/head
rstoyanchev 3 years ago
parent
commit
cb39b07088
  1. 34
      spring-core/src/testFixtures/java/org/springframework/core/testfixture/codec/AbstractEncoderTests.java
  2. 2
      spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java
  3. 48
      spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java
  4. 12
      spring-web/src/test/java/org/springframework/http/codec/json/Jackson2SmileEncoderTests.java
  5. 19
      spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java
  6. 26
      spring-web/src/test/kotlin/org/springframework/http/codec/json/KotlinSerializationJsonEncoderTests.kt

34
spring-core/src/testFixtures/java/org/springframework/core/testfixture/codec/AbstractEncoderTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -81,7 +81,7 @@ public abstract class AbstractEncoderTests<E extends Encoder<?>> extends Abstrac
* Helper methods that tests for a variety of encoding scenarios. This methods * Helper methods that tests for a variety of encoding scenarios. This methods
* invokes: * invokes:
* <ul> * <ul>
* <li>{@link #testEncode(Publisher, ResolvableType, Consumer, MimeType, Map)}</li> * <li>{@link #testEncode(Publisher, ResolvableType, MimeType, Map, Consumer)}</li>
* <li>{@link #testEncodeError(Publisher, ResolvableType, MimeType, Map)}</li> * <li>{@link #testEncodeError(Publisher, ResolvableType, MimeType, Map)}</li>
* <li>{@link #testEncodeCancel(Publisher, ResolvableType, MimeType, Map)}</li> * <li>{@link #testEncodeCancel(Publisher, ResolvableType, MimeType, Map)}</li>
* <li>{@link #testEncodeEmpty(ResolvableType, MimeType, Map)}</li> * <li>{@link #testEncodeEmpty(ResolvableType, MimeType, Map)}</li>
@ -94,30 +94,32 @@ public abstract class AbstractEncoderTests<E extends Encoder<?>> extends Abstrac
*/ */
protected <T> void testEncodeAll(Publisher<? extends T> input, Class<? extends T> inputClass, protected <T> void testEncodeAll(Publisher<? extends T> input, Class<? extends T> inputClass,
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) { Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) {
testEncodeAll(input, ResolvableType.forClass(inputClass), stepConsumer, null, null);
testEncodeAll(input, ResolvableType.forClass(inputClass), null, null, stepConsumer);
} }
/** /**
* Helper methods that tests for a variety of decoding scenarios. This methods * Helper methods that tests for a variety of decoding scenarios. This methods
* invokes: * invokes:
* <ul> * <ul>
* <li>{@link #testEncode(Publisher, ResolvableType, Consumer, MimeType, Map)}</li> * <li>{@link #testEncode(Publisher, ResolvableType, MimeType, Map, Consumer)}</li>
* <li>{@link #testEncodeError(Publisher, ResolvableType, MimeType, Map)}</li> * <li>{@link #testEncodeError(Publisher, ResolvableType, MimeType, Map)}</li>
* <li>{@link #testEncodeCancel(Publisher, ResolvableType, MimeType, Map)}</li> * <li>{@link #testEncodeCancel(Publisher, ResolvableType, MimeType, Map)}</li>
* <li>{@link #testEncodeEmpty(ResolvableType, MimeType, Map)}</li> * <li>{@link #testEncodeEmpty(ResolvableType, MimeType, Map)}</li>
* </ul> * </ul>
* *
* @param <T> the output type
* @param input the input to be provided to the encoder * @param input the input to be provided to the encoder
* @param inputType the input type * @param inputType the input type
* @param stepConsumer a consumer to {@linkplain StepVerifier verify} the output
* @param mimeType the mime type to use for decoding. May be {@code null}. * @param mimeType the mime type to use for decoding. May be {@code null}.
* @param hints the hints used for decoding. May be {@code null}. * @param hints the hints used for decoding. May be {@code null}.
* @param <T> the output type * @param stepConsumer a consumer to {@linkplain StepVerifier verify} the output
*/ */
protected <T> void testEncodeAll(Publisher<? extends T> input, ResolvableType inputType, protected <T> void testEncodeAll(Publisher<? extends T> input, ResolvableType inputType,
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) {
testEncode(input, inputType, stepConsumer, mimeType, hints);
testEncode(input, inputType, mimeType, hints, stepConsumer);
testEncodeError(input, inputType, mimeType, hints); testEncodeError(input, inputType, mimeType, hints);
testEncodeCancel(input, inputType, mimeType, hints); testEncodeCancel(input, inputType, mimeType, hints);
testEncodeEmpty(inputType, mimeType, hints); testEncodeEmpty(inputType, mimeType, hints);
@ -133,25 +135,25 @@ public abstract class AbstractEncoderTests<E extends Encoder<?>> extends Abstrac
*/ */
protected <T> void testEncode(Publisher<? extends T> input, Class<? extends T> inputClass, protected <T> void testEncode(Publisher<? extends T> input, Class<? extends T> inputClass,
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) { Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) {
testEncode(input, ResolvableType.forClass(inputClass), stepConsumer, null, null);
testEncode(input, ResolvableType.forClass(inputClass), null, null, stepConsumer);
} }
/** /**
* Test a standard {@link Encoder#encode encode} scenario. * Test a standard {@link Encoder#encode encode} scenario.
* *
* @param <T> the output type
* @param input the input to be provided to the encoder * @param input the input to be provided to the encoder
* @param inputType the input type * @param inputType the input type
* @param stepConsumer a consumer to {@linkplain StepVerifier verify} the output
* @param mimeType the mime type to use for decoding. May be {@code null}. * @param mimeType the mime type to use for decoding. May be {@code null}.
* @param hints the hints used for decoding. May be {@code null}. * @param hints the hints used for decoding. May be {@code null}.
* @param <T> the output type * @param stepConsumer a consumer to {@linkplain StepVerifier verify} the output
*/ */
protected <T> void testEncode(Publisher<? extends T> input, ResolvableType inputType, protected <T> void testEncode(Publisher<? extends T> input, ResolvableType inputType,
Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) { Consumer<StepVerifier.FirstStep<DataBuffer>> stepConsumer) {
Flux<DataBuffer> result = encoder().encode(input, this.bufferFactory, inputType, Flux<DataBuffer> result = encoder().encode(input, this.bufferFactory, inputType, mimeType, hints);
mimeType, hints);
StepVerifier.FirstStep<DataBuffer> step = StepVerifier.create(result); StepVerifier.FirstStep<DataBuffer> step = StepVerifier.create(result);
stepConsumer.accept(step); stepConsumer.accept(step);
} }

2
spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

48
spring-web/src/test/java/org/springframework/http/codec/json/Jackson2JsonEncoderTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -95,12 +95,12 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
new Pojo("foofoo", "barbar"), new Pojo("foofoo", "barbar"),
new Pojo("foofoofoo", "barbarbar")); new Pojo("foofoofoo", "barbarbar"));
testEncodeAll(input, ResolvableType.forClass(Pojo.class), step -> step testEncodeAll(input, ResolvableType.forClass(Pojo.class), APPLICATION_STREAM_JSON, null, step -> step
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}\n")) .consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}\n"))
.consumeNextWith(expectString("{\"foo\":\"foofoo\",\"bar\":\"barbar\"}\n")) .consumeNextWith(expectString("{\"foo\":\"foofoo\",\"bar\":\"barbar\"}\n"))
.consumeNextWith(expectString("{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}\n")) .consumeNextWith(expectString("{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}\n"))
.verifyComplete(), .verifyComplete()
APPLICATION_STREAM_JSON, null); );
} }
@Test // SPR-15866 @Test // SPR-15866
@ -168,15 +168,15 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
new Pojo("foofoofoo", "barbarbar") new Pojo("foofoofoo", "barbarbar")
); );
testEncode(input, ResolvableType.forClass(Pojo.class), step -> step testEncode(input, ResolvableType.forClass(Pojo.class), barMediaType, null, step -> step
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}\n") .consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}\n")
.andThen(DataBufferUtils::release)) .andThen(DataBufferUtils::release))
.consumeNextWith(expectString("{\"foo\":\"foofoo\",\"bar\":\"barbar\"}\n") .consumeNextWith(expectString("{\"foo\":\"foofoo\",\"bar\":\"barbar\"}\n")
.andThen(DataBufferUtils::release)) .andThen(DataBufferUtils::release))
.consumeNextWith(expectString("{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}\n") .consumeNextWith(expectString("{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}\n")
.andThen(DataBufferUtils::release)) .andThen(DataBufferUtils::release))
.verifyComplete(), .verifyComplete()
barMediaType, null); );
} }
@Test @Test
@ -190,11 +190,10 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
ResolvableType type = ResolvableType.forClass(JacksonViewBean.class); ResolvableType type = ResolvableType.forClass(JacksonViewBean.class);
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView1.class); Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView1.class);
testEncode(input, type, step -> step testEncode(input, type, null, hints, step -> step
.consumeNextWith(expectString("{\"withView1\":\"with\"}") .consumeNextWith(expectString("{\"withView1\":\"with\"}").andThen(DataBufferUtils::release))
.andThen(DataBufferUtils::release)) .verifyComplete()
.verifyComplete(), );
null, hints);
} }
@Test @Test
@ -208,11 +207,10 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
ResolvableType type = ResolvableType.forClass(JacksonViewBean.class); ResolvableType type = ResolvableType.forClass(JacksonViewBean.class);
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView3.class); Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView3.class);
testEncode(input, type, step -> step testEncode(input, type, null, hints, step -> step
.consumeNextWith(expectString("{\"withoutView\":\"without\"}") .consumeNextWith(expectString("{\"withoutView\":\"without\"}").andThen(DataBufferUtils::release))
.andThen(DataBufferUtils::release)) .verifyComplete()
.verifyComplete(), );
null, hints);
} }
@Test @Test
@ -227,11 +225,10 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
ResolvableType type = ResolvableType.forClass(MappingJacksonValue.class); ResolvableType type = ResolvableType.forClass(MappingJacksonValue.class);
testEncode(Mono.just(jacksonValue), type, step -> step testEncode(Mono.just(jacksonValue), type, null, Collections.emptyMap(), step -> step
.consumeNextWith(expectString("{\"withView1\":\"with\"}") .consumeNextWith(expectString("{\"withView1\":\"with\"}").andThen(DataBufferUtils::release))
.andThen(DataBufferUtils::release)) .verifyComplete()
.verifyComplete(), );
null, Collections.emptyMap());
} }
@Test // gh-22771 @Test // gh-22771
@ -252,11 +249,12 @@ public class Jackson2JsonEncoderTests extends AbstractEncoderTests<Jackson2JsonE
@Test @Test
public void encodeAscii() { public void encodeAscii() {
Mono<Object> input = Mono.just(new Pojo("foo", "bar")); Mono<Object> input = Mono.just(new Pojo("foo", "bar"));
MimeType mimeType = new MimeType("application", "json", StandardCharsets.US_ASCII);
testEncode(input, ResolvableType.forClass(Pojo.class), step -> step testEncode(input, ResolvableType.forClass(Pojo.class), mimeType, null, step -> step
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}")) .consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}"))
.verifyComplete(), .verifyComplete()
new MimeType("application", "json", StandardCharsets.US_ASCII), null); );
} }

12
spring-web/src/test/java/org/springframework/http/codec/json/Jackson2SmileEncoderTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2020 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -108,17 +108,13 @@ public class Jackson2SmileEncoderTests extends AbstractEncoderTests<Jackson2Smil
} }
@Test @Test
public void encodeError() throws Exception { public void encodeError() {
Mono<Pojo> input = Mono.error(new InputException()); Mono<Pojo> input = Mono.error(new InputException());
testEncode(input, Pojo.class, step -> step.expectError(InputException.class).verify());
testEncode(input, Pojo.class, step -> step
.expectError(InputException.class)
.verify());
} }
@Test @Test
public void encodeAsStream() throws Exception { public void encodeAsStream() {
Pojo pojo1 = new Pojo("foo", "bar"); Pojo pojo1 = new Pojo("foo", "bar");
Pojo pojo2 = new Pojo("foofoo", "barbar"); Pojo pojo2 = new Pojo("foofoo", "barbar");
Pojo pojo3 = new Pojo("foofoofoo", "barbarbar"); Pojo pojo3 = new Pojo("foofoofoo", "barbarbar");

19
spring-web/src/test/java/org/springframework/http/codec/xml/Jaxb2XmlEncoderTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -71,8 +71,8 @@ public class Jaxb2XmlEncoderTests extends AbstractEncoderTests<Jaxb2XmlEncoder>
Mono<Pojo> input = Mono.just(new Pojo("foofoo", "barbar")); Mono<Pojo> input = Mono.just(new Pojo("foofoo", "barbar"));
testEncode(input, Pojo.class, step -> step testEncode(input, Pojo.class, step -> step
.consumeNextWith( .consumeNextWith(expectXml(
expectXml("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" + "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
"<pojo><bar>barbar</bar><foo>foofoo</foo></pojo>")) "<pojo><bar>barbar</bar><foo>foofoo</foo></pojo>"))
.verifyComplete()); .verifyComplete());
} }
@ -80,10 +80,7 @@ public class Jaxb2XmlEncoderTests extends AbstractEncoderTests<Jaxb2XmlEncoder>
@Test @Test
public void encodeError() { public void encodeError() {
Flux<Pojo> input = Flux.error(RuntimeException::new); Flux<Pojo> input = Flux.error(RuntimeException::new);
testEncode(input, Pojo.class, step -> step.expectError(RuntimeException.class).verify());
testEncode(input, Pojo.class, step -> step
.expectError(RuntimeException.class)
.verify());
} }
@Test @Test
@ -91,9 +88,11 @@ public class Jaxb2XmlEncoderTests extends AbstractEncoderTests<Jaxb2XmlEncoder>
Mono<Container> input = Mono.just(new Container()); Mono<Container> input = Mono.just(new Container());
testEncode(input, Pojo.class, step -> step testEncode(input, Pojo.class, step -> step
.consumeNextWith( .consumeNextWith(expectXml(
expectXml("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" + "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
"<container><foo><name>name1</name></foo><bar><title>title1</title></bar></container>")) "<container>" +
"<foo><name>name1</name></foo><bar><title>title1</title></bar>" +
"</container>"))
.verifyComplete()); .verifyComplete());
} }

26
spring-web/src/test/kotlin/org/springframework/http/codec/json/KotlinSerializationJsonEncoderTests.kt

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2021 the original author or authors. * Copyright 2002-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -65,25 +65,23 @@ class KotlinSerializationJsonEncoderTests : AbstractEncoderTests<KotlinSerializa
Pojo("foofoo", "barbar"), Pojo("foofoo", "barbar"),
Pojo("foofoofoo", "barbarbar") Pojo("foofoofoo", "barbarbar")
) )
testEncode(input, Pojo::class.java, { step: FirstStep<DataBuffer?> -> testEncode(input, Pojo::class.java, { step: FirstStep<DataBuffer?> -> step
step .consumeNextWith(expectString("[" +
.consumeNextWith(expectString("[" + "{\"foo\":\"foo\",\"bar\":\"bar\"}," +
"{\"foo\":\"foo\",\"bar\":\"bar\"}," + "{\"foo\":\"foofoo\",\"bar\":\"barbar\"}," +
"{\"foo\":\"foofoo\",\"bar\":\"barbar\"}," + "{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}]")
"{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}]") .andThen { dataBuffer: DataBuffer? -> DataBufferUtils.release(dataBuffer) })
.andThen { dataBuffer: DataBuffer? -> DataBufferUtils.release(dataBuffer) }) .verifyComplete()
.verifyComplete()
}) })
} }
@Test @Test
fun encodeMono() { fun encodeMono() {
val input = Mono.just(Pojo("foo", "bar")) val input = Mono.just(Pojo("foo", "bar"))
testEncode(input, Pojo::class.java, { step: FirstStep<DataBuffer?> -> testEncode(input, Pojo::class.java, { step: FirstStep<DataBuffer?> -> step
step .consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}")
.consumeNextWith(expectString("{\"foo\":\"foo\",\"bar\":\"bar\"}") .andThen { dataBuffer: DataBuffer? -> DataBufferUtils.release(dataBuffer) })
.andThen { dataBuffer: DataBuffer? -> DataBufferUtils.release(dataBuffer) }) .verifyComplete()
.verifyComplete()
}) })
} }

Loading…
Cancel
Save