Refactor tests with ScriptedSubscriber

Reactor recently added the `ScriptedSubscriber` in its new
`reactor-addons` module. This `Subscriber` revissits the previous
`TestSubscriber` with many improvements, including:

* scripting each expectation
* builder API that guides you until the final verification step
* virtual time support

This commit refactor all existing tests to use this new
infrastructure and removed the `TestSubscriber` implementation.

Issue: SPR-14800
This commit is contained in:
Brian Clozel
2016-10-18 09:06:33 +02:00
parent 827bc78e34
commit 99a3210859
50 changed files with 873 additions and 1911 deletions

View File

@@ -21,11 +21,11 @@ import java.util.Collections;
import org.junit.Test;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.assertArrayEquals;
@@ -57,12 +57,12 @@ public class ByteArrayDecoderTests extends AbstractDataBufferAllocatingTestCase
Flux<byte[]> output = this.decoder.decode(source,
ResolvableType.forClassWithGenerics(Publisher.class, byte[].class),
null, Collections.emptyMap());
TestSubscriber
.subscribe(output)
.assertNoError()
.assertComplete()
.assertValuesWith(bytes -> assertArrayEquals("foo".getBytes(), bytes),
bytes -> assertArrayEquals("bar".getBytes(), bytes));
ScriptedSubscriber
.<byte[]>create()
.consumeNextWith(bytes -> assertArrayEquals("foo".getBytes(), bytes))
.consumeNextWith(bytes -> assertArrayEquals("bar".getBytes(), bytes))
.expectComplete()
.verify(output);
}
}

View File

@@ -24,11 +24,11 @@ import org.junit.Before;
import org.junit.Test;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.assertArrayEquals;
@@ -66,17 +66,20 @@ public class ByteArrayEncoderTests extends AbstractDataBufferAllocatingTestCase
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory,
ResolvableType.forClassWithGenerics(Publisher.class, ByteBuffer.class),
null, Collections.emptyMap());
TestSubscriber
.subscribe(output)
.assertValuesWith(b -> {
ScriptedSubscriber
.<DataBuffer>create()
.consumeNextWith(b -> {
byte[] buf = new byte[3];
b.read(buf);
assertArrayEquals(fooBytes, buf);
}, b -> {
})
.consumeNextWith(b -> {
byte[] buf = new byte[3];
b.read(buf);
assertArrayEquals(barBytes, buf);
});
})
.expectComplete()
.verify(output);
}
}

View File

@@ -22,11 +22,11 @@ import java.util.Collections;
import org.junit.Test;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.assertFalse;
@@ -57,10 +57,10 @@ public class ByteBufferDecoderTests extends AbstractDataBufferAllocatingTestCase
Flux<ByteBuffer> output = this.decoder.decode(source,
ResolvableType.forClassWithGenerics(Publisher.class, ByteBuffer.class),
null, Collections.emptyMap());
TestSubscriber
.subscribe(output)
.assertNoError()
.assertComplete()
.assertValues(ByteBuffer.wrap("foo".getBytes()), ByteBuffer.wrap("bar".getBytes()));
ScriptedSubscriber.<ByteBuffer>create()
.expectNext(ByteBuffer.wrap("foo".getBytes()), ByteBuffer.wrap("bar".getBytes()))
.expectComplete()
.verify(output);
}
}

View File

@@ -24,11 +24,11 @@ import org.junit.Before;
import org.junit.Test;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.assertArrayEquals;
@@ -67,17 +67,19 @@ public class ByteBufferEncoderTests extends AbstractDataBufferAllocatingTestCase
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory,
ResolvableType.forClassWithGenerics(Publisher.class, ByteBuffer.class),
null, Collections.emptyMap());
TestSubscriber
.subscribe(output)
.assertValuesWith(b -> {
ScriptedSubscriber.<DataBuffer>create()
.consumeNextWith(b -> {
byte[] buf = new byte[3];
b.read(buf);
assertArrayEquals(fooBytes, buf);
}, b -> {
})
.consumeNextWith(b -> {
byte[] buf = new byte[3];
b.read(buf);
assertArrayEquals(barBytes, buf);
});
})
.expectComplete()
.verify(output);
}
}

View File

@@ -23,11 +23,11 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import reactor.core.publisher.Flux;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.assertFalse;
@@ -61,27 +61,25 @@ public class CharSequenceEncoderTests extends AbstractDataBufferAllocatingTestCa
}
@Test
public void writeString() throws InterruptedException {
public void writeString() {
Flux<String> stringFlux = Flux.just("foo");
Flux<DataBuffer> output = Flux.from(
this.encoder.encode(stringFlux, this.bufferFactory, null, null,Collections.emptyMap()));
TestSubscriber
.subscribe(output)
.assertNoError()
.assertComplete()
.assertValuesWith(stringConsumer("foo"));
this.encoder.encode(stringFlux, this.bufferFactory, null, null, Collections.emptyMap()));
ScriptedSubscriber.<DataBuffer>create()
.consumeNextWith(stringConsumer("foo"))
.expectComplete()
.verify(output);
}
@Test
public void writeStringBuilder() throws InterruptedException {
public void writeStringBuilder() {
Flux<StringBuilder> stringBuilderFlux = Flux.just(new StringBuilder("foo"));
Flux<DataBuffer> output = Flux.from(
this.encoder.encode(stringBuilderFlux, this.bufferFactory, null, null, Collections.emptyMap()));
TestSubscriber
.subscribe(output)
.assertNoError()
.assertComplete()
.assertValuesWith(stringConsumer("foo"));
ScriptedSubscriber.<DataBuffer>create()
.consumeNextWith(stringConsumer("foo"))
.expectComplete()
.verify(output);
}
}

View File

@@ -21,6 +21,7 @@ import java.util.Collections;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.ByteArrayResource;
@@ -28,7 +29,6 @@ import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeTypeUtils;
import org.springframework.util.StreamUtils;
@@ -64,21 +64,18 @@ public class ResourceDecoderTests extends AbstractDataBufferAllocatingTestCase {
Flux<Resource> result = this.decoder
.decode(source, ResolvableType.forClass(Resource.class), null, Collections.emptyMap());
TestSubscriber
.subscribe(result)
.assertNoError()
.assertComplete()
.assertValuesWith(resource -> {
ScriptedSubscriber.<Resource>create()
.consumeNextWith(resource -> {
try {
byte[] bytes =
StreamUtils.copyToByteArray(resource.getInputStream());
byte[] bytes = StreamUtils.copyToByteArray(resource.getInputStream());
assertEquals("foobar", new String(bytes));
}
catch (IOException e) {
fail(e.getMessage());
}
});
})
.expectComplete()
.verify(result);
}
}

View File

@@ -22,6 +22,7 @@ import java.util.Collections;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.ByteArrayResource;
@@ -29,7 +30,6 @@ import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.assertTrue;
@@ -62,14 +62,13 @@ public class ResourceEncoderTests extends AbstractDataBufferAllocatingTestCase {
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory,
ResolvableType.forClass(Resource.class),
null, Collections.emptyMap());
TestSubscriber
.subscribe(output)
.assertNoError()
.assertComplete()
.assertValuesWith(stringConsumer(s));
null, Collections.emptyMap());
ScriptedSubscriber
.<DataBuffer>create()
.consumeNextWith(stringConsumer(s))
.expectComplete()
.verify(output);
}
}

View File

@@ -16,9 +16,6 @@
package org.springframework.core.codec;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
@@ -26,6 +23,7 @@ import org.junit.Before;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.ByteArrayResource;
@@ -36,11 +34,14 @@ import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.core.io.buffer.support.DataBufferTestUtils;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.util.StringUtils;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Test cases for {@link ResourceRegionEncoder} class.
*
@@ -80,10 +81,10 @@ public class ResourceRegionEncoderTests extends AbstractDataBufferAllocatingTest
ResolvableType.forClass(ResourceRegion.class), MimeTypeUtils.APPLICATION_OCTET_STREAM
, Collections.emptyMap());
TestSubscriber.subscribe(result)
.assertNoError()
.assertComplete()
.assertValuesWith(stringConsumer("Spring"));
ScriptedSubscriber.<DataBuffer>create()
.consumeNextWith(stringConsumer("Spring"))
.expectComplete()
.verify(result);
}
@Test
@@ -110,36 +111,34 @@ public class ResourceRegionEncoderTests extends AbstractDataBufferAllocatingTest
return previous;
});
TestSubscriber
.subscribe(reduced)
.assertNoError()
.assertComplete()
.assertValuesWith(dataBuffer -> {
String content = DataBufferTestUtils.dumpString(dataBuffer, StandardCharsets.UTF_8);
String[] ranges = StringUtils.tokenizeToStringArray(content, "\r\n", false, true);
assertThat(ranges[0], is("--" + boundary));
assertThat(ranges[1], is("Content-Type: text/plain"));
assertThat(ranges[2], is("Content-Range: bytes 0-5/39"));
assertThat(ranges[3], is("Spring"));
assertThat(ranges[4], is("--" + boundary));
assertThat(ranges[5], is("Content-Type: text/plain"));
assertThat(ranges[6], is("Content-Range: bytes 7-15/39"));
assertThat(ranges[7], is("Framework"));
assertThat(ranges[8], is("--" + boundary));
assertThat(ranges[9], is("Content-Type: text/plain"));
assertThat(ranges[10], is("Content-Range: bytes 17-20/39"));
assertThat(ranges[11], is("test"));
assertThat(ranges[12], is("--" + boundary));
assertThat(ranges[13], is("Content-Type: text/plain"));
assertThat(ranges[14], is("Content-Range: bytes 22-38/39"));
assertThat(ranges[15], is("resource content."));
assertThat(ranges[16], is("--" + boundary + "--"));
});
ScriptedSubscriber.<DataBuffer>create()
.consumeNextWith(buf -> {
String content = DataBufferTestUtils.dumpString(buf, StandardCharsets.UTF_8);
String[] ranges = StringUtils.tokenizeToStringArray(content, "\r\n",
false, true);
String[] expected = new String[] {
"--" + boundary,
"Content-Type: text/plain",
"Content-Range: bytes 0-5/39",
"Spring",
"--" + boundary,
"Content-Type: text/plain",
"Content-Range: bytes 7-15/39",
"Framework",
"--" + boundary,
"Content-Type: text/plain",
"Content-Range: bytes 17-20/39",
"test",
"--" + boundary,
"Content-Type: text/plain",
"Content-Range: bytes 22-38/39",
"resource content.",
"--" + boundary + "--"
};
assertArrayEquals(expected, ranges);
})
.expectComplete()
.verify(reduced);
}
}

View File

@@ -21,11 +21,11 @@ import java.util.Collections;
import org.junit.Test;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.subscriber.ScriptedSubscriber;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.tests.TestSubscriber;
import org.springframework.util.MimeTypeUtils;
import static org.junit.Assert.assertFalse;
@@ -61,11 +61,11 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
Flux<DataBuffer> source = Flux.just(stringBuffer("foo"), stringBuffer("bar"), stringBuffer("baz"));
Flux<String> output = this.decoder.decode(source, ResolvableType.forClass(String.class),
null, Collections.emptyMap());
ScriptedSubscriber
.<String>create()
.expectNext("foo", "bar", "baz")
.expectComplete().verify(output);
TestSubscriber.subscribe(output)
.assertNoError()
.assertComplete()
.assertValues("foo", "bar", "baz");
}
@Test
@@ -75,10 +75,11 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
Flux<DataBuffer> source = Flux.just(fooBar, baz);
Flux<String> output = decoder.decode(source, ResolvableType.forClass(String.class),
null, Collections.emptyMap());
ScriptedSubscriber
.<String>create()
.expectNext("\n", "foo\r", "\n", "bar\r", "\n", "baz")
.expectComplete().verify(output);
TestSubscriber.subscribe(output)
.assertNoError()
.assertComplete().assertValues("\n", "foo\r", "\n", "bar\r", "\n", "baz");
}
@Test
@@ -87,10 +88,11 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
Flux<String> output = this.decoder.decode(source, ResolvableType.forClass(String.class),
null, Collections.emptyMap());
TestSubscriber.subscribe(output)
.assertNoError()
.assertComplete()
.assertNoValues();
ScriptedSubscriber
.<String>create()
.expectNextCount(0)
.expectComplete().verify(output);
}
@Test
@@ -99,7 +101,11 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
Flux<String> output = this.decoder.decode(source,
ResolvableType.forClass(String.class), null, Collections.emptyMap());
TestSubscriber.subscribe(output).assertValues("");
ScriptedSubscriber
.<String>create()
.expectNext("")
.expectComplete().verify(output);
}
@Test
@@ -109,10 +115,11 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
Mono<String> output = this.decoder.decodeToMono(source,
ResolvableType.forClass(String.class), null, Collections.emptyMap());
TestSubscriber.subscribe(output)
.assertNoError()
.assertComplete()
.assertValues("foobarbaz");
ScriptedSubscriber
.<String>create()
.expectNext("foobarbaz")
.expectComplete()
.verify(output);
}
@Test
@@ -121,10 +128,11 @@ public class StringDecoderTests extends AbstractDataBufferAllocatingTestCase {
Mono<String> output = this.decoder.decodeToMono(source,
ResolvableType.forClass(String.class), null, Collections.emptyMap());
TestSubscriber.subscribe(output)
.assertNoError()
.assertComplete()
.assertNoValues();
ScriptedSubscriber
.<String>create()
.expectNextCount(0)
.expectComplete()
.verify(output);
}
}

View File

@@ -27,7 +27,7 @@ import org.junit.runners.Parameterized;
import org.springframework.core.io.buffer.support.DataBufferTestUtils;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
/**
* @author Arjen Poutsma
@@ -40,7 +40,7 @@ public abstract class AbstractDataBufferAllocatingTestCase {
@Parameterized.Parameters(name = "{0}")
public static Object[][] dataBufferFactories() {
return new Object[][]{
return new Object[][] {
{new NettyDataBufferFactory(new UnpooledByteBufAllocator(true))},
{new NettyDataBufferFactory(new UnpooledByteBufAllocator(false))},
{new NettyDataBufferFactory(new PooledByteBufAllocator(true))},

View File

@@ -24,9 +24,9 @@ import java.nio.file.StandardOpenOption;
import org.junit.Test;
import reactor.core.publisher.Flux;
import org.springframework.tests.TestSubscriber;
import reactor.test.subscriber.ScriptedSubscriber;
import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
/**
* @author Arjen Poutsma
@@ -39,13 +39,13 @@ public class DataBufferUtilsTests extends AbstractDataBufferAllocatingTestCase {
FileChannel channel = FileChannel.open(Paths.get(uri), StandardOpenOption.READ);
Flux<DataBuffer> flux = DataBufferUtils.read(channel, this.bufferFactory, 3);
TestSubscriber
.subscribe(flux)
.assertNoError()
.assertComplete()
.assertValuesWith(
stringConsumer("foo"), stringConsumer("bar"),
stringConsumer("baz"), stringConsumer("qux"));
ScriptedSubscriber
.<DataBuffer>create()
.consumeNextWith(stringConsumer("foo"))
.consumeNextWith(stringConsumer("bar"))
.consumeNextWith(stringConsumer("baz"))
.consumeNextWith(stringConsumer("qux"))
.expectComplete().verify(flux);
assertFalse(channel.isOpen());
}
@@ -56,77 +56,74 @@ public class DataBufferUtilsTests extends AbstractDataBufferAllocatingTestCase {
FileChannel channel = FileChannel.open(Paths.get(uri), StandardOpenOption.READ);
Flux<DataBuffer> flux = DataBufferUtils.read(channel, this.bufferFactory, 5);
TestSubscriber
.subscribe(flux)
.assertNoError()
.assertComplete()
.assertValuesWith(
stringConsumer("fooba"), stringConsumer("rbazq"),
stringConsumer("ux")
);
ScriptedSubscriber
.<DataBuffer>create()
.consumeNextWith(stringConsumer("fooba"))
.consumeNextWith(stringConsumer("rbazq"))
.consumeNextWith(stringConsumer("ux"))
.expectComplete().verify(flux);
assertFalse(channel.isOpen());
}
@Test
public void readInputStream() {
public void readInputStream() throws Exception {
InputStream is = DataBufferUtilsTests.class.getResourceAsStream("DataBufferUtilsTests.txt");
Flux<DataBuffer> flux = DataBufferUtils.read(is, this.bufferFactory, 3);
TestSubscriber
.subscribe(flux)
.assertNoError()
.assertComplete()
.assertValuesWith(
stringConsumer("foo"), stringConsumer("bar"),
stringConsumer("baz"), stringConsumer("qux"));
ScriptedSubscriber
.<DataBuffer>create()
.consumeNextWith(stringConsumer("foo"))
.consumeNextWith(stringConsumer("bar"))
.consumeNextWith(stringConsumer("baz"))
.consumeNextWith(stringConsumer("qux"))
.expectComplete().verify(flux);
}
@Test
public void takeUntilByteCount() {
public void takeUntilByteCount() throws Exception {
DataBuffer foo = stringBuffer("foo");
DataBuffer bar = stringBuffer("bar");
DataBuffer baz = stringBuffer("baz");
Flux<DataBuffer> flux = Flux.just(foo, bar, baz);
Flux<DataBuffer> result = DataBufferUtils.takeUntilByteCount(flux, 5L);
TestSubscriber
.subscribe(result)
.assertNoError()
.assertComplete()
.assertValuesWith(stringConsumer("foo"), stringConsumer("ba"));
ScriptedSubscriber
.<DataBuffer>create()
.consumeNextWith(stringConsumer("foo"))
.consumeNextWith(stringConsumer("ba"))
.expectComplete().verify(result);
release(baz);
}
@Test
public void skipUntilByteCount() {
public void skipUntilByteCount() throws Exception {
DataBuffer foo = stringBuffer("foo");
DataBuffer bar = stringBuffer("bar");
DataBuffer baz = stringBuffer("baz");
Flux<DataBuffer> flux = Flux.just(foo, bar, baz);
Flux<DataBuffer> result = DataBufferUtils.skipUntilByteCount(flux, 5L);
TestSubscriber
.subscribe(result)
.assertNoError()
.assertComplete()
.assertValuesWith(stringConsumer("r"), stringConsumer("baz"));
ScriptedSubscriber
.<DataBuffer>create()
.consumeNextWith(stringConsumer("r"))
.consumeNextWith(stringConsumer("baz"))
.expectComplete().verify(result);
}
@Test
public void skipUntilByteCountShouldSkipAll() {
public void skipUntilByteCountShouldSkipAll() throws Exception {
DataBuffer foo = stringBuffer("foo");
DataBuffer bar = stringBuffer("bar");
DataBuffer baz = stringBuffer("baz");
Flux<DataBuffer> flux = Flux.just(foo, bar, baz);
Flux<DataBuffer> result = DataBufferUtils.skipUntilByteCount(flux, 9L);
TestSubscriber
.subscribe(result)
.assertNoError()
.assertNoValues()
.assertComplete();
ScriptedSubscriber
.<DataBuffer>create()
.expectNextCount(0)
.expectComplete().verify(result);
}
}