From 83f4c3f9991620b6a0e63548d4e8644c1e998ac2 Mon Sep 17 00:00:00 2001 From: Oliver Trosien Date: Tue, 5 Jul 2022 08:59:33 +0200 Subject: [PATCH] JUnit 4 to JUnit 5 migration (#344) * JUnit 5 (WIP) * switch to jupiter engine * junit5 latest * code cleanup * Update fahrschein-http-apache/src/test/java/org/zalando/fahrschein/http/apache/HttpComponentsRequestFactoryTest.java Co-authored-by: Malte * Remove hamcrest-compose * fix test Co-authored-by: Malte --- .../groovy/fahrschein.java-conventions.gradle | 16 +- .../e2e/NakadiClientEnd2EndTest.java | 41 ++-- .../HttpComponentsRequestFactoryTest.java | 22 +- .../fahrschein/http/api/ContentTypeTest.java | 13 +- .../fahrschein/http/api/HeadersImplTest.java | 19 +- .../jdk11/JavaNetHeadersDelegateTest.java | 32 ++- .../http/jdk11/JavaNetRequestFactoryTest.java | 14 +- .../http/simple/SimpleRequestFactoryTest.java | 14 +- .../http/spring/SpringRequestFactoryTest.java | 14 +- fahrschein-http-test-support/build.gradle | 3 +- .../http/test/AbstractRequestFactoryTest.java | 8 +- fahrschein-test-support/build.gradle | 2 +- .../test/AbstractCursorManagerTest.java | 8 +- .../test/AbstractPartitionManagerTest.java | 48 ++-- .../MetadataTypeResolverTest.java | 26 +- fahrschein/build.gradle | 1 - .../fahrschein/AccessTokenProviderTest.java | 2 +- .../AuthorizedRequestFactoryTest.java | 6 +- ...ntityAcceptEncodingRequestFactoryTest.java | 4 +- .../fahrschein/LowLevelStreamBuilderTest.java | 2 +- .../fahrschein/ManagedCursorManagerTest.java | 14 +- .../org/zalando/fahrschein/MockServer.java | 5 +- .../zalando/fahrschein/NakadiClientTest.java | 53 +++-- .../NakadiReaderDeserializationTest.java | 2 +- .../zalando/fahrschein/NakadiReaderTest.java | 222 +++++++++--------- .../ProblemHandlingRequestTest.java | 71 +++--- .../fahrschein/StreamParametersTest.java | 50 ++-- .../zalando/fahrschein/domain/CursorTest.java | 4 +- .../fahrschein/domain/MetadataTest.java | 21 +- gradle.properties | 2 +- 30 files changed, 384 insertions(+), 355 deletions(-) diff --git a/buildSrc/src/main/groovy/fahrschein.java-conventions.gradle b/buildSrc/src/main/groovy/fahrschein.java-conventions.gradle index dd7e1342..9d56288f 100644 --- a/buildSrc/src/main/groovy/fahrschein.java-conventions.gradle +++ b/buildSrc/src/main/groovy/fahrschein.java-conventions.gradle @@ -17,6 +17,10 @@ java { } } +test { + useJUnitPlatform() +} + tasks.withType(JavaCompile).configureEach { options.compilerArgs << '-parameters' options.compilerArgs << '-Xlint:all' @@ -31,11 +35,13 @@ dependencies { testRuntimeOnly("org.slf4j:slf4j-simple:${property('slf4j.version')}") { because "we want the slf4j-simple logger implementation available at test runtime" } + + // JUnit 5 + testImplementation("org.junit.jupiter:junit-jupiter:${property('junit.version')}") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${property('junit.version')}") + testImplementation("org.mockito:mockito-junit-jupiter:${property('mockito.version')}") testImplementation("org.mockito:mockito-core:${property('mockito.version')}") { - because "we want mockito to be used in tests" - } - testImplementation("junit:junit:${property('junit.version')}") { - because "we want a common version JUnit across all projects" + because "We want Mockito to be used in tests" } testImplementation('org.hamcrest:hamcrest:2.2') { because "we want to have hamcrest available for all testing" @@ -49,6 +55,7 @@ configurations.all { resolutionStrategy.dependencySubstitution { substitute(platform(module('commons-logging:commons-logging'))). using module("org.slf4j:jcl-over-slf4j:${property('slf4j.version')}") + // hamcrest changed package coordinates. Make sure to only include the new one. substitute(platform(module('org.hamcrest:hamcrest-core'))). using module("org.hamcrest:hamcrest:2.2") } @@ -57,6 +64,7 @@ configurations.all { test { finalizedBy jacocoTestReport // report is always generated after tests run } + jacocoTestReport { dependsOn test // tests are required to run before generating the report } diff --git a/fahrschein-e2e-test/src/test/java/org/zalando/fahrschein/e2e/NakadiClientEnd2EndTest.java b/fahrschein-e2e-test/src/test/java/org/zalando/fahrschein/e2e/NakadiClientEnd2EndTest.java index eede47f4..610414e5 100644 --- a/fahrschein-e2e-test/src/test/java/org/zalando/fahrschein/e2e/NakadiClientEnd2EndTest.java +++ b/fahrschein-e2e-test/src/test/java/org/zalando/fahrschein/e2e/NakadiClientEnd2EndTest.java @@ -11,10 +11,10 @@ import okhttp3.logging.HttpLoggingInterceptor; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mockito; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +29,7 @@ import org.zalando.fahrschein.domain.Subscription; import org.zalando.fahrschein.http.apache.HttpComponentsRequestFactory; import org.zalando.fahrschein.http.api.ContentEncoding; +import org.zalando.fahrschein.http.api.Request; import org.zalando.fahrschein.http.api.RequestFactory; import org.zalando.fahrschein.http.jdk11.JavaNetRequestFactory; import org.zalando.fahrschein.http.simple.SimpleRequestFactory; @@ -55,7 +56,6 @@ /* * Enable wire-debug by running with -Djdk.httpclient.HttpClient.log=requests */ -@RunWith(Parameterized.class) public class NakadiClientEnd2EndTest extends NakadiTestWithDockerCompose { private static final Logger logger = LoggerFactory.getLogger("okhttp3.wire"); @@ -78,17 +78,8 @@ public class NakadiClientEnd2EndTest extends NakadiTestWithDockerCompose { objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); } - public final RequestFactory requestFactory; - - private NakadiClient nakadiClient; - - public NakadiClientEnd2EndTest(RequestFactory requestFactory, String testName) { - this.requestFactory = requestFactory; - } - - @Before - public void setUpNakadiClient() { - nakadiClient = NakadiClient + private NakadiClient setUpNakadiClient(RequestFactory requestFactory) { + return NakadiClient .builder(getNakadiUrl(), requestFactory) .withObjectMapper(objectMapper) .build(); @@ -141,12 +132,14 @@ private static RequestFactory simple(ContentEncoding contentEncoding) { return new SimpleRequestFactory(contentEncoding); } - @Test - public void testPublish() throws IOException { - publish(UUID.randomUUID().toString()); + @ParameterizedTest + @MethodSource("getRequestFactories") + public void testPublish(RequestFactory requestFactory) throws IOException { + NakadiClient nakadiClient = setUpNakadiClient(requestFactory); + publish(nakadiClient, UUID.randomUUID().toString()); } - private List publish(String testId) throws IOException { + private List publish(NakadiClient nakadiClient, String testId) throws IOException { createEventTypes("/eventtypes", testId); List events = IntStream.range(0, 10) .mapToObj( @@ -156,8 +149,10 @@ private List publish(String testId) throws IOException { return events; } - @Test - public void testSubscribe() throws IOException, EventAlreadyProcessedException { + @ParameterizedTest + @MethodSource("getRequestFactories") + public void testSubscribe(RequestFactory requestFactory) throws IOException, EventAlreadyProcessedException { + NakadiClient nakadiClient = setUpNakadiClient(requestFactory); String testId = UUID.randomUUID().toString(); createEventTypes("/eventtypes", testId); final Listener listener = subscriptionListener(); @@ -181,7 +176,7 @@ public void testSubscribe() throws IOException, EventAlreadyProcessedException { } return; }));; - List eventOrderNumbers = publish(testId).stream().map(e -> e.orderNumber).collect(toList()); + List eventOrderNumbers = publish(nakadiClient, testId).stream().map(e -> e.orderNumber).collect(toList()); // verifies that every order number that was published got consumed for (String on: eventOrderNumbers) { Mockito.verify(listener, timeout(10000).atLeastOnce()).accept( diff --git a/fahrschein-http-apache/src/test/java/org/zalando/fahrschein/http/apache/HttpComponentsRequestFactoryTest.java b/fahrschein-http-apache/src/test/java/org/zalando/fahrschein/http/apache/HttpComponentsRequestFactoryTest.java index ea29d938..cc07fdda 100644 --- a/fahrschein-http-apache/src/test/java/org/zalando/fahrschein/http/apache/HttpComponentsRequestFactoryTest.java +++ b/fahrschein-http-apache/src/test/java/org/zalando/fahrschein/http/apache/HttpComponentsRequestFactoryTest.java @@ -3,28 +3,33 @@ import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import org.zalando.fahrschein.http.api.ContentEncoding; import org.zalando.fahrschein.http.api.Request; import org.zalando.fahrschein.http.api.RequestFactory; import org.zalando.fahrschein.http.test.AbstractRequestFactoryTest; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; + import java.io.IOException; import java.net.SocketTimeoutException; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class HttpComponentsRequestFactoryTest extends AbstractRequestFactoryTest { - @Test(expected = SocketTimeoutException.class) + @Test public void testTimeout() throws IOException { // given server.createContext("/timeout", exchange -> { try { Thread.sleep(10l); exchange.sendResponseHeaders(201, 0); - } catch (InterruptedException e) { } + } catch (InterruptedException e) { + fail("Unexpected Exception thrown"); + } }); // when @@ -32,7 +37,10 @@ public void testTimeout() throws IOException { final CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).build(); RequestFactory f = new HttpComponentsRequestFactory(httpClient, ContentEncoding.GZIP); Request r = f.createRequest(serverAddress.resolve("/timeout"), "GET"); - r.execute(); + + assertThrows(SocketTimeoutException.class, () -> { + r.execute(); + }); } public RequestFactory defaultRequestFactory(ContentEncoding contentEncoding) { diff --git a/fahrschein-http-api/src/test/java/org/zalando/fahrschein/http/api/ContentTypeTest.java b/fahrschein-http-api/src/test/java/org/zalando/fahrschein/http/api/ContentTypeTest.java index 47d62729..fdefb6d6 100644 --- a/fahrschein-http-api/src/test/java/org/zalando/fahrschein/http/api/ContentTypeTest.java +++ b/fahrschein-http-api/src/test/java/org/zalando/fahrschein/http/api/ContentTypeTest.java @@ -1,11 +1,12 @@ package org.zalando.fahrschein.http.api; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.HashSet; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; public class ContentTypeTest { @@ -33,9 +34,11 @@ public void shouldParseProblemJson() { assertEquals("problem+json", contentType.getSubtype()); } - @Test(expected = IllegalArgumentException.class) + @Test public void shouldFailOnIllegalContentType() { - ContentType.valueOf("foo bar"); + assertThrows(IllegalArgumentException.class, () -> { + ContentType.valueOf("foo bar"); + }); } @Test diff --git a/fahrschein-http-api/src/test/java/org/zalando/fahrschein/http/api/HeadersImplTest.java b/fahrschein-http-api/src/test/java/org/zalando/fahrschein/http/api/HeadersImplTest.java index 1f4e14b7..15105bf4 100644 --- a/fahrschein-http-api/src/test/java/org/zalando/fahrschein/http/api/HeadersImplTest.java +++ b/fahrschein-http-api/src/test/java/org/zalando/fahrschein/http/api/HeadersImplTest.java @@ -1,6 +1,6 @@ package org.zalando.fahrschein.http.api; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.util.HashSet; @@ -8,8 +8,9 @@ import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; import static java.util.Collections.singletonList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; public class HeadersImplTest { @Test @@ -57,15 +58,17 @@ public void shouldCopyHeaders() { assertEquals(new HashSet<>(asList("Content-Type", "Content-Length")), copy.headerNames()); } - @Test(expected = UnsupportedOperationException.class) + @Test public void readOnlyViewShouldNotSupportAdd() { final HeadersImpl readOnlyHeaders = new HeadersImpl(new HeadersImpl(), true); - readOnlyHeaders.add("Content-Type", "application/json"); + assertThrows(UnsupportedOperationException.class, () -> { + readOnlyHeaders.add("Content-Type", "application/json"); + }); } - @Test(expected = UnsupportedOperationException.class) + @Test public void readOnlyViewShouldNotSupportPut() { final HeadersImpl headers = new HeadersImpl(); headers.put("Content-Type", "text/plain"); @@ -74,7 +77,9 @@ public void readOnlyViewShouldNotSupportPut() { final HeadersImpl readOnlyHeaders = new HeadersImpl(headers, true); assertEquals("text/plain", readOnlyHeaders.getFirst("Content-Type")); - readOnlyHeaders.put("Content-Type", "application/json"); + assertThrows(UnsupportedOperationException.class, () -> { + readOnlyHeaders.put("Content-Type", "application/json"); + }); } @Test diff --git a/fahrschein-http-jdk11/src/test/java/org/zalando/fahrschein/http/jdk11/JavaNetHeadersDelegateTest.java b/fahrschein-http-jdk11/src/test/java/org/zalando/fahrschein/http/jdk11/JavaNetHeadersDelegateTest.java index 95159748..58c22ca4 100644 --- a/fahrschein-http-jdk11/src/test/java/org/zalando/fahrschein/http/jdk11/JavaNetHeadersDelegateTest.java +++ b/fahrschein-http-jdk11/src/test/java/org/zalando/fahrschein/http/jdk11/JavaNetHeadersDelegateTest.java @@ -1,6 +1,6 @@ package org.zalando.fahrschein.http.jdk11; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.zalando.fahrschein.http.api.ContentType; import org.zalando.fahrschein.http.api.Headers; @@ -12,8 +12,9 @@ import static java.util.Collections.emptyList; import static java.util.Collections.emptySet; import static java.util.Collections.singletonList; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; public class JavaNetHeadersDelegateTest { @@ -54,19 +55,23 @@ public void shouldReturnEmptyListForUnknownHeaders() { assertEquals(emptyList(), headers.get(Headers.CONTENT_TYPE)); } - @Test(expected = UnsupportedOperationException.class) + @Test public void readOnlyViewShouldNotSupportAdd() { final Headers headers = new JavaNetHeadersDelegate(requestBuilder().build().headers()); - headers.add(Headers.CONTENT_TYPE, "application/json"); + assertThrows(UnsupportedOperationException.class, () -> { + headers.add(Headers.CONTENT_TYPE, "application/json"); + }); } - @Test(expected = UnsupportedOperationException.class) + @Test public void readOnlyViewShouldNotSupportPut() { final Headers headers = new JavaNetHeadersDelegate(requestBuilder() .setHeader(Headers.CONTENT_TYPE, "text/plain") .setHeader(Headers.CONTENT_ENCODING, "gzip").build().headers()); - headers.put(Headers.CONTENT_TYPE, "application/json"); + assertThrows(UnsupportedOperationException.class, () -> { + headers.put(Headers.CONTENT_TYPE, "application/json"); + }); } @Test @@ -80,22 +85,25 @@ public void shouldGetContentType() { assertEquals(ContentType.TEXT_PLAIN, contentType); } - @Test(expected = UnsupportedOperationException.class) + @Test public void shouldNotSetContentLength() { final Headers headers = new JavaNetHeadersDelegate(requestBuilder().build().headers()); - headers.setContentLength(2000L); + assertThrows(UnsupportedOperationException.class, () -> { + headers.setContentLength(2000L); + }); } - @Test(expected = UnsupportedOperationException.class) + @Test public void shouldNotSetContentType() { final Headers headers = new JavaNetHeadersDelegate(requestBuilder().build().headers()); - headers.setContentType(ContentType.TEXT_PLAIN); + assertThrows(UnsupportedOperationException.class, () -> { + headers.setContentType(ContentType.TEXT_PLAIN); + }); } @Test public void shouldReturnMinusOneForUnknownContentLength() { final Headers headers = new JavaNetHeadersDelegate(requestBuilder().build().headers()); - assertEquals(-1L, headers.getContentLength()); } } diff --git a/fahrschein-http-jdk11/src/test/java/org/zalando/fahrschein/http/jdk11/JavaNetRequestFactoryTest.java b/fahrschein-http-jdk11/src/test/java/org/zalando/fahrschein/http/jdk11/JavaNetRequestFactoryTest.java index 52ea862b..b81f009c 100644 --- a/fahrschein-http-jdk11/src/test/java/org/zalando/fahrschein/http/jdk11/JavaNetRequestFactoryTest.java +++ b/fahrschein-http-jdk11/src/test/java/org/zalando/fahrschein/http/jdk11/JavaNetRequestFactoryTest.java @@ -1,19 +1,23 @@ package org.zalando.fahrschein.http.jdk11; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.jupiter.MockitoExtension; import org.zalando.fahrschein.http.api.ContentEncoding; import org.zalando.fahrschein.http.api.Request; import org.zalando.fahrschein.http.api.RequestFactory; import org.zalando.fahrschein.http.test.AbstractRequestFactoryTest; +import static org.junit.jupiter.api.Assertions.assertThrows; + import java.io.IOException; import java.net.http.HttpClient; +import java.net.http.HttpTimeoutException; import java.time.Duration; import java.util.Optional; -@RunWith(MockitoJUnitRunner.class) +@ExtendWith(MockitoExtension.class) public class JavaNetRequestFactoryTest extends AbstractRequestFactoryTest { @Override @@ -21,7 +25,7 @@ public RequestFactory defaultRequestFactory(ContentEncoding contentEncoding) { return new JavaNetRequestFactory(HttpClient.newHttpClient(), Optional.empty(), contentEncoding); } - @Test(expected = java.net.http.HttpTimeoutException.class) + @Test public void testTimeout() throws IOException { // given server.createContext("/timeout", exchange -> { @@ -34,7 +38,7 @@ public void testTimeout() throws IOException { // when RequestFactory f = new JavaNetRequestFactory(HttpClient.newBuilder().build(), Optional.of(Duration.ofMillis(1)), ContentEncoding.IDENTITY); Request r = f.createRequest(serverAddress.resolve("/timeout"), "GET"); - r.execute(); + assertThrows(HttpTimeoutException.class, () -> r.execute()); } } diff --git a/fahrschein-http-simple/src/test/java/org/zalando/fahrschein/http/simple/SimpleRequestFactoryTest.java b/fahrschein-http-simple/src/test/java/org/zalando/fahrschein/http/simple/SimpleRequestFactoryTest.java index acdcdf3b..ce0060ec 100644 --- a/fahrschein-http-simple/src/test/java/org/zalando/fahrschein/http/simple/SimpleRequestFactoryTest.java +++ b/fahrschein-http-simple/src/test/java/org/zalando/fahrschein/http/simple/SimpleRequestFactoryTest.java @@ -1,8 +1,8 @@ package org.zalando.fahrschein.http.simple; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import org.zalando.fahrschein.http.api.ContentEncoding; import org.zalando.fahrschein.http.api.Request; import org.zalando.fahrschein.http.api.RequestFactory; @@ -11,10 +11,12 @@ import java.io.IOException; import java.net.SocketTimeoutException; -@RunWith(MockitoJUnitRunner.class) +import static org.junit.jupiter.api.Assertions.assertThrows; + +@ExtendWith(MockitoExtension.class) public class SimpleRequestFactoryTest extends AbstractRequestFactoryTest { - @Test(expected = SocketTimeoutException.class) + @Test public void testTimeout() throws IOException { // given server.createContext("/timeout", exchange -> { @@ -28,7 +30,7 @@ public void testTimeout() throws IOException { SimpleRequestFactory f = new SimpleRequestFactory(ContentEncoding.IDENTITY); f.setReadTimeout(1); Request r = f.createRequest(serverAddress.resolve("/timeout"), "GET"); - r.execute(); + assertThrows(SocketTimeoutException.class, () -> r.execute()); } @Override diff --git a/fahrschein-http-spring/src/test/java/org/zalando/fahrschein/http/spring/SpringRequestFactoryTest.java b/fahrschein-http-spring/src/test/java/org/zalando/fahrschein/http/spring/SpringRequestFactoryTest.java index 6453b116..a84dcf1a 100644 --- a/fahrschein-http-spring/src/test/java/org/zalando/fahrschein/http/spring/SpringRequestFactoryTest.java +++ b/fahrschein-http-spring/src/test/java/org/zalando/fahrschein/http/spring/SpringRequestFactoryTest.java @@ -1,9 +1,9 @@ package org.zalando.fahrschein.http.spring; import okhttp3.OkHttpClient; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; import org.zalando.fahrschein.http.api.ContentEncoding; import org.zalando.fahrschein.http.api.Request; @@ -14,10 +14,12 @@ import java.net.SocketTimeoutException; import java.util.concurrent.TimeUnit; -@RunWith(MockitoJUnitRunner.class) +import static org.junit.jupiter.api.Assertions.assertThrows; + +@ExtendWith(MockitoExtension.class) public class SpringRequestFactoryTest extends AbstractRequestFactoryTest { - @Test(expected = SocketTimeoutException.class) + @Test public void testTimeout() throws IOException { // given server.createContext("/timeout", exchange -> { @@ -35,7 +37,7 @@ public void testTimeout() throws IOException { OkHttp3ClientHttpRequestFactory clientHttpRequestFactory = new OkHttp3ClientHttpRequestFactory(client); SpringRequestFactory f = new SpringRequestFactory(clientHttpRequestFactory, ContentEncoding.IDENTITY); Request r = f.createRequest(serverAddress.resolve("/timeout"), "GET"); - r.execute(); + assertThrows(SocketTimeoutException.class, () -> r.execute()); } @Override diff --git a/fahrschein-http-test-support/build.gradle b/fahrschein-http-test-support/build.gradle index 23613962..95c97df3 100644 --- a/fahrschein-http-test-support/build.gradle +++ b/fahrschein-http-test-support/build.gradle @@ -7,6 +7,7 @@ dependencies { testFixturesApi project(':fahrschein-http-api') testFixturesImplementation "com.github.luben:zstd-jni:1.5.2-2" testFixturesImplementation "org.mockito:mockito-core:${property('mockito.version')}" - testFixturesImplementation "junit:junit:${property('junit.version')}" + testFixturesImplementation("org.junit.jupiter:junit-jupiter:${property('junit.version')}") + testFixturesImplementation('org.hamcrest:hamcrest:2.2') } diff --git a/fahrschein-http-test-support/src/testFixtures/java/org/zalando/fahrschein/http/test/AbstractRequestFactoryTest.java b/fahrschein-http-test-support/src/testFixtures/java/org/zalando/fahrschein/http/test/AbstractRequestFactoryTest.java index 63f43157..707f50cf 100644 --- a/fahrschein-http-test-support/src/testFixtures/java/org/zalando/fahrschein/http/test/AbstractRequestFactoryTest.java +++ b/fahrschein-http-test-support/src/testFixtures/java/org/zalando/fahrschein/http/test/AbstractRequestFactoryTest.java @@ -4,8 +4,8 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mockito; @@ -34,7 +34,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; public abstract class AbstractRequestFactoryTest { @@ -43,7 +43,7 @@ public abstract class AbstractRequestFactoryTest { protected static HttpServer server; protected static URI serverAddress; - @BeforeClass + @BeforeAll public static void startServer() throws IOException { server = HttpServer.create(new InetSocketAddress("localhost", 0), 1); serverAddress = URI.create("http://localhost:" + server.getAddress().getPort()); diff --git a/fahrschein-test-support/build.gradle b/fahrschein-test-support/build.gradle index 212e17c6..1c62ce4a 100644 --- a/fahrschein-test-support/build.gradle +++ b/fahrschein-test-support/build.gradle @@ -5,6 +5,6 @@ plugins { dependencies { testFixturesApi project(':fahrschein') - testFixturesImplementation "junit:junit:${property('junit.version')}" + testFixturesImplementation("org.junit.jupiter:junit-jupiter:${property('junit.version')}") testFixturesImplementation "org.springframework:spring-tx:${property('spring.version')}" } diff --git a/fahrschein-test-support/src/testFixtures/java/org/zalando/fahrschein/test/AbstractCursorManagerTest.java b/fahrschein-test-support/src/testFixtures/java/org/zalando/fahrschein/test/AbstractCursorManagerTest.java index e284a79d..9a0fba1c 100644 --- a/fahrschein-test-support/src/testFixtures/java/org/zalando/fahrschein/test/AbstractCursorManagerTest.java +++ b/fahrschein-test-support/src/testFixtures/java/org/zalando/fahrschein/test/AbstractCursorManagerTest.java @@ -1,6 +1,6 @@ package org.zalando.fahrschein.test; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.transaction.annotation.Transactional; import org.zalando.fahrschein.CursorManager; import org.zalando.fahrschein.domain.Cursor; @@ -12,9 +12,9 @@ import java.util.Comparator; import java.util.List; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; @Transactional public abstract class AbstractCursorManagerTest { diff --git a/fahrschein-test-support/src/testFixtures/java/org/zalando/fahrschein/test/AbstractPartitionManagerTest.java b/fahrschein-test-support/src/testFixtures/java/org/zalando/fahrschein/test/AbstractPartitionManagerTest.java index 7173ea51..38739b1a 100644 --- a/fahrschein-test-support/src/testFixtures/java/org/zalando/fahrschein/test/AbstractPartitionManagerTest.java +++ b/fahrschein-test-support/src/testFixtures/java/org/zalando/fahrschein/test/AbstractPartitionManagerTest.java @@ -1,9 +1,6 @@ package org.zalando.fahrschein.test; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.junit.jupiter.api.Test; import org.springframework.transaction.annotation.Transactional; import org.zalando.fahrschein.PartitionManager; import org.zalando.fahrschein.domain.Lock; @@ -14,14 +11,15 @@ import java.util.Optional; import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; // Looks like the Transactional annotation has to be on the class actually declaring the methods @Transactional public abstract class AbstractPartitionManagerTest { - @Rule - public final ExpectedException expectedException = ExpectedException.none(); - protected abstract PartitionManager partitionManager(); protected abstract PartitionManager partitionManagerForAnotherConsumer(); @@ -32,74 +30,76 @@ protected List partitions(String... ids) { @Test public void shouldLock() { final Optional locked = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-1"); - Assert.assertTrue(locked.isPresent()); + assertTrue(locked.isPresent()); } @Test public void shouldAllowLockBySameNode() { final Optional locked1 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-1"); - Assert.assertTrue(locked1.isPresent()); + assertTrue(locked1.isPresent()); final Optional locked2 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-1"); - Assert.assertTrue(locked2.isPresent()); + assertTrue(locked2.isPresent()); } @Test public void shouldNotLockAlreadyLocked() { final Optional locked1 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-1"); - Assert.assertTrue(locked1.isPresent()); + assertTrue(locked1.isPresent()); final Optional locked2 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-2"); - Assert.assertFalse(locked2.isPresent()); + assertFalse(locked2.isPresent()); } @Test public void shouldLockIndependentConsumers() { final Optional locked1 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "consumer-1-node-1"); - Assert.assertTrue(locked1.isPresent()); + assertTrue(locked1.isPresent()); final Optional locked2 = partitionManagerForAnotherConsumer().lockPartitions("sales-order-placed", partitions("0"), "consumer-2-node-1"); - Assert.assertTrue(locked2.isPresent()); + assertTrue(locked2.isPresent()); } @Test public void shouldLockIndependentEvents() { final Optional locked1 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-1"); - Assert.assertTrue(locked1.isPresent()); + assertTrue(locked1.isPresent()); final Optional locked2 = partitionManager().lockPartitions("address-changed", partitions("0"), "node-1"); - Assert.assertTrue(locked2.isPresent()); + assertTrue(locked2.isPresent()); } @Test public void shouldLockIndependentPartitions() { final Optional locked1 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-1"); - Assert.assertTrue(locked1.isPresent()); + assertTrue(locked1.isPresent()); final Optional locked2 = partitionManager().lockPartitions("sales-order-placed", partitions("1"), "node-1"); - Assert.assertTrue(locked2.isPresent()); + assertTrue(locked2.isPresent()); } @Test public void shouldUnlock() throws InterruptedException { final Optional locked1 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-1"); - Assert.assertTrue(locked1.isPresent()); + assertTrue(locked1.isPresent()); partitionManager().unlockPartitions(locked1.get()); final Optional locked2 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-2"); - Assert.assertTrue(locked2.isPresent()); + assertTrue(locked2.isPresent()); } @Test public void shouldFailOnInvalidUnlock() throws InterruptedException { final Optional locked1 = partitionManager().lockPartitions("sales-order-placed", partitions("0"), "node-1"); - Assert.assertTrue(locked1.isPresent()); + assertTrue(locked1.isPresent()); + + IllegalStateException expectedException = assertThrows(IllegalStateException.class, () -> { + partitionManager().unlockPartitions(new Lock("sales-order-placed", "node-2", partitions("0"))); + }); - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Could not unlock"); + assertEquals("Could not unlock [sales-order-placed] by [node-2] because it is locked by [node-1]", expectedException.getMessage()); - partitionManager().unlockPartitions(new Lock("sales-order-placed", "node-2", partitions("0"))); } } diff --git a/fahrschein-typeresolver/src/test/java/org/zalando/fahrschein/typeresolver/MetadataTypeResolverTest.java b/fahrschein-typeresolver/src/test/java/org/zalando/fahrschein/typeresolver/MetadataTypeResolverTest.java index 9589e9d1..2f7e7fde 100644 --- a/fahrschein-typeresolver/src/test/java/org/zalando/fahrschein/typeresolver/MetadataTypeResolverTest.java +++ b/fahrschein-typeresolver/src/test/java/org/zalando/fahrschein/typeresolver/MetadataTypeResolverTest.java @@ -10,13 +10,15 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.annotation.JsonTypeResolver; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.zalando.fahrschein.domain.Event; import org.zalando.fahrschein.domain.Metadata; import java.io.IOException; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class MetadataTypeResolverTest { private static final String ORDER_SHIPPED = "{\"foo\":\"bar\",\"metadata\":{\"occurred_at\":\"2017-03-15T02:00:48.497Z\",\"eid\":\"36931a5d-74d6-3033-84ea-a8336197c4ce\",\"event_type\":\"order_shipped\",\"partition\":\"0\",\"received_at\":\"2017-03-15T02:00:52.355Z\",\"flow_id\":\"GEI8VPtEd02DSBMBnV1GjChS\",\"version\":\"0.1.0\"},\"order_number\":\"10410018540147\",\"flow_id\":\"RzhTJ2sLTVigDrxhTrlQ_Q\"}"; private static final String ORDER_CREATED = "{\"foo\":\"baz\",\"metadata\":{\"occurred_at\":\"2017-03-15T02:00:47.689Z\",\"eid\":\"a3e25946-5ae9-3964-91fa-26ecb7588d67\",\"event_type\":\"order_created\",\"partition\":\"0\",\"received_at\":\"2017-03-15T02:00:51.437Z\",\"flow_id\":\"GH5kZY88Zkj6O5QKVnPBQbZw\",\"version\":\"0.1.0\"},\"order_number\":\"10410018540147\",\"customer_number\":\"123456\",\"shipping_country\":\"DE\",\"flow_id\":\"R5brW3FzQ16WL5vdNb0jCA\",\"payment_method\":\"INVOICE\"}"; @@ -97,11 +99,11 @@ public void shouldDeserializeOrderShipped() throws IOException { final OrderEvent event = objectMapper.readValue(ORDER_SHIPPED, OrderEvent.class); final Metadata metadata = event.getMetadata(); - Assert.assertEquals("36931a5d-74d6-3033-84ea-a8336197c4ce", metadata.getEid()); - Assert.assertEquals("order_shipped", metadata.getEventType()); - Assert.assertEquals("10410018540147", event.getOrderNumber()); + assertEquals("36931a5d-74d6-3033-84ea-a8336197c4ce", metadata.getEid()); + assertEquals("order_shipped", metadata.getEventType()); + assertEquals("10410018540147", event.getOrderNumber()); - Assert.assertTrue(event instanceof OrderShippedEvent); + assertTrue(event instanceof OrderShippedEvent); } @Test @@ -109,12 +111,12 @@ public void shouldDeserializeOrderCreated() throws IOException { final OrderEvent event = objectMapper.readValue(ORDER_CREATED, OrderEvent.class); final Metadata metadata = event.getMetadata(); - Assert.assertEquals("a3e25946-5ae9-3964-91fa-26ecb7588d67", metadata.getEid()); - Assert.assertEquals("order_created", metadata.getEventType()); - Assert.assertEquals("10410018540147", event.getOrderNumber()); + assertEquals("a3e25946-5ae9-3964-91fa-26ecb7588d67", metadata.getEid()); + assertEquals("order_created", metadata.getEventType()); + assertEquals("10410018540147", event.getOrderNumber()); - Assert.assertTrue(event instanceof OrderCreatedEvent); - Assert.assertEquals("123456", ((OrderCreatedEvent)event).getCustomerNumber()); - Assert.assertEquals("INVOICE", ((OrderCreatedEvent)event).getPaymentMethod()); + assertTrue(event instanceof OrderCreatedEvent); + assertEquals("123456", ((OrderCreatedEvent)event).getCustomerNumber()); + assertEquals("INVOICE", ((OrderCreatedEvent)event).getPaymentMethod()); } } diff --git a/fahrschein/build.gradle b/fahrschein/build.gradle index b943c249..154c55bc 100644 --- a/fahrschein/build.gradle +++ b/fahrschein/build.gradle @@ -15,7 +15,6 @@ dependencies { testImplementation ('com.jayway.jsonpath:json-path:2.7.0') { exclude group: "org.ow2.asm", module: "asm" } - testImplementation 'org.hobsoft.hamcrest:hamcrest-compose:0.3.0' testImplementation 'com.google.code.findbugs:jsr305:2.0.1' } diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/AccessTokenProviderTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/AccessTokenProviderTest.java index 33e60626..e837ffe0 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/AccessTokenProviderTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/AccessTokenProviderTest.java @@ -1,6 +1,6 @@ package org.zalando.fahrschein; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.io.IOException; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/AuthorizedRequestFactoryTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/AuthorizedRequestFactoryTest.java index 361c4246..8c7239ec 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/AuthorizedRequestFactoryTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/AuthorizedRequestFactoryTest.java @@ -1,7 +1,7 @@ package org.zalando.fahrschein; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.zalando.fahrschein.http.api.Headers; import org.zalando.fahrschein.http.api.HeadersImpl; import org.zalando.fahrschein.http.api.Request; @@ -24,7 +24,7 @@ public class AuthorizedRequestFactoryTest { private final RequestFactory delegate = mock(RequestFactory.class); private final AuthorizedRequestFactory unit = new AuthorizedRequestFactory(delegate, () -> BEARER_TOKEN); - @Before + @BeforeEach public void setUp() throws Exception { final Request request = mockRequest(); when(delegate.createRequest(any(), anyString())).thenReturn(request); diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/IdentityAcceptEncodingRequestFactoryTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/IdentityAcceptEncodingRequestFactoryTest.java index d791f2bd..78a50f54 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/IdentityAcceptEncodingRequestFactoryTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/IdentityAcceptEncodingRequestFactoryTest.java @@ -1,6 +1,6 @@ package org.zalando.fahrschein; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.zalando.fahrschein.http.api.Headers; import org.zalando.fahrschein.http.api.HeadersImpl; @@ -11,7 +11,7 @@ import java.net.URI; import java.util.Arrays; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/LowLevelStreamBuilderTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/LowLevelStreamBuilderTest.java index 7a6e5811..f860e30a 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/LowLevelStreamBuilderTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/LowLevelStreamBuilderTest.java @@ -1,7 +1,7 @@ package org.zalando.fahrschein; import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatcher; import org.zalando.fahrschein.domain.Cursor; import org.zalando.fahrschein.domain.Partition; diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/ManagedCursorManagerTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/ManagedCursorManagerTest.java index 2b2f1b74..ec3097a4 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/ManagedCursorManagerTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/ManagedCursorManagerTest.java @@ -1,7 +1,7 @@ package org.zalando.fahrschein; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.zalando.fahrschein.domain.Cursor; import org.zalando.fahrschein.domain.Subscription; import org.zalando.fahrschein.http.api.ContentType; @@ -16,16 +16,16 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.fail; public class ManagedCursorManagerTest { private MockServer server; private ManagedCursorManager cursorManager; - @Before + @BeforeEach public void foo() { this.server = new MockServer(); this.cursorManager = new ManagedCursorManager(URI.create("http://example.com/"), this.server); diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/MockServer.java b/fahrschein/src/test/java/org/zalando/fahrschein/MockServer.java index dcb0f9bc..e8eca807 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/MockServer.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/MockServer.java @@ -4,6 +4,7 @@ import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.spi.json.JacksonJsonProvider; import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; +import org.hamcrest.CoreMatchers; import org.hamcrest.Matcher; import org.mockito.Mockito; import org.zalando.fahrschein.http.api.ContentType; @@ -22,9 +23,9 @@ import java.util.LinkedHashMap; import java.util.Map; +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -137,7 +138,7 @@ public void verify() throws IOException { } if (expectedContentType != null) { - assertEquals("requestContentType", requestHeaders.getContentType(), expectedContentType); + assertThat(requestHeaders.getContentType(), is(expectedContentType)); } for (Map.Entry> entry : expectedHeaders.entrySet()) { diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/NakadiClientTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/NakadiClientTest.java index 36ba2674..893c909c 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/NakadiClientTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/NakadiClientTest.java @@ -1,9 +1,7 @@ package org.zalando.fahrschein; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.zalando.fahrschein.domain.Partition; import org.zalando.fahrschein.domain.Subscription; import org.zalando.fahrschein.domain.SubscriptionRequest; @@ -21,7 +19,10 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.Mockito.mock; import static org.zalando.fahrschein.AuthorizationBuilder.authorization; @@ -38,13 +39,10 @@ public String getId() { } } - @Rule - public final ExpectedException expectedException = ExpectedException.none(); - private MockServer server; private NakadiClient client; - @Before + @BeforeEach public void setup() { final MockServer clientHttpRequestFactory = new MockServer(); @@ -231,12 +229,14 @@ public void shouldThrowExceptionOnSubscriptionDeleteFailure() throws IOException " \"detail\": \"Subscription not found.\"\n" + "}").setup(); - expectedException.expect(IOProblem.class); - expectedException.expectMessage("Problem [http://httpstatus.es/404] with status [404]: [Not Found] [Subscription not found.]"); - client.deleteSubscription("123"); + IOProblem expectedException = assertThrows(IOProblem.class, () -> { + client.deleteSubscription("123"); + }); server.verify(); + + assertEquals("Problem [http://httpstatus.es/404] with status [404]: [Not Found] [Subscription not found.]", expectedException.getMessage()); } @Test @@ -249,12 +249,13 @@ public void shouldThrowExceptionOnSubscriptionToUnknownEvent() throws IOExceptio " \"detail\": \"Eventtype does not exist.\"\n" + "}").setup(); - expectedException.expect(IOProblem.class); - expectedException.expectMessage("Problem [http://httpstatus.es/422] with status [422]: [Unprocessable Entity] [Eventtype does not exist.]"); - client.subscribe("nakadi-client-test", Collections.singleton("non-existing-event"), "nakadi-client-test-consumer", SubscriptionRequest.Position.BEGIN, null, null); + IOProblem expectedException = assertThrows(IOProblem.class, () -> { + client.subscribe("nakadi-client-test", Collections.singleton("non-existing-event"), "nakadi-client-test-consumer", SubscriptionRequest.Position.BEGIN, null, null); + }); server.verify(); + assertEquals("Problem [http://httpstatus.es/422] with status [422]: [Unprocessable Entity] [Eventtype does not exist.]", expectedException.getMessage()); } @Test @@ -273,15 +274,15 @@ public void shouldHandleMultiStatusWhenPublishing() throws IOException { server.expectRequestTo("http://example.com/event-types/foobar/events", "POST") .andExpectJsonPath("$[0].id", equalTo("1")) .andExpectJsonPath("$[1].id", equalTo("2")) - .andRespondWith(207, ContentType.APPLICATION_JSON, "[{\"publishing_status\":\"failed\",\"step\":\"validating\",\"detail\":\"baz\"}]") + .andRespondWith(207, ContentType.APPLICATION_JSON, "[{\"eid\":\"event-one\",\"publishing_status\":\"failed\",\"step\":\"validating\",\"detail\":\"baz\"}]") .setup(); - expectedException.expect(EventPublishingException.class); - expectedException.expectMessage("returned status [failed] in step [validating] with detail [baz]"); - - client.publish("foobar", asList(new SomeEvent("1"), new SomeEvent("2"))); - + EventPublishingException expectedException = assertThrows(EventPublishingException.class, () -> { + client.publish("foobar", asList(new SomeEvent("1"), new SomeEvent("2"))); + }); server.verify(); + + assertEquals("Event publishing of [event-one] returned status [failed] in step [validating] with detail [baz]", expectedException.getMessage()); } @Test @@ -302,15 +303,17 @@ public void shouldHandleBatchItemResponseWhenPublishing() throws IOException { server.expectRequestTo("http://example.com/event-types/foobar/events", "POST") .andExpectJsonPath("$[0].id", equalTo("1")) .andExpectJsonPath("$[1].id", equalTo("2")) - .andRespondWith(422, ContentType.APPLICATION_JSON, "[{\"publishing_status\":\"aborted\",\"step\":\"publishing\",\"detail\":\"baz\"}]") + .andRespondWith(422, ContentType.APPLICATION_JSON, "[{\"eid\":\"some-event\",\"publishing_status\":\"aborted\",\"step\":\"publishing\",\"detail\":\"baz\"}]") .setup(); - expectedException.expect(EventPublishingException.class); - expectedException.expectMessage("returned status [aborted] in step [publishing] with detail [baz]"); - client.publish("foobar", asList(new SomeEvent("1"), new SomeEvent("2"))); + Throwable expectedException = assertThrows(EventPublishingException.class, () -> { + client.publish("foobar", asList(new SomeEvent("1"), new SomeEvent("2"))); + }); server.verify(); + assertEquals("Event publishing of [some-event] returned status [aborted] in step [publishing] with detail [baz]", expectedException.getMessage()); + } } diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/NakadiReaderDeserializationTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/NakadiReaderDeserializationTest.java index 8c2cffe5..86e86354 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/NakadiReaderDeserializationTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/NakadiReaderDeserializationTest.java @@ -8,7 +8,7 @@ import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import org.hamcrest.Matchers; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.zalando.fahrschein.domain.AbstractDataChangeEvent; import org.zalando.fahrschein.domain.DataChangeEvent; import org.zalando.fahrschein.domain.DataOperation; diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/NakadiReaderTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/NakadiReaderTest.java index 6cc2e1b0..25a6418a 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/NakadiReaderTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/NakadiReaderTest.java @@ -2,12 +2,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import org.hamcrest.Matchers; -import org.hobsoft.hamcrest.compose.ComposeMatchers; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatchers; import org.zalando.fahrschein.domain.Cursor; @@ -20,6 +15,7 @@ import org.zalando.fahrschein.http.api.Response; import java.io.ByteArrayInputStream; +import java.io.EOFException; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -45,10 +41,16 @@ import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; @@ -67,9 +69,6 @@ public class NakadiReaderTest { @SuppressWarnings("unchecked") private final Listener listener = (Listener)mock(Listener.class); - @Rule - public final ExpectedException expectedException = ExpectedException.none(); - public static class SomeEvent { private String id; @@ -93,14 +92,14 @@ public void shouldNotRetryInitialConnection() throws IOException { final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(IOException.class); - expectedException.expectMessage(equalTo("Initial connection failed")); - - nakadiReader.run(); + IOException expectedException = assertThrows(IOException.class, () -> { + nakadiReader.run(); + }); + assertThat(expectedException.getMessage(), equalTo("Initial connection failed")); } @Test - public void shouldNotReconnectWithoutBackoff() throws IOException, InterruptedException, BackoffException { + public void shouldNotReconnectWithoutBackoff() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream emptyInputStream = new ByteArrayInputStream(new byte[0]); when(response.getBody()).thenReturn(emptyInputStream); @@ -113,15 +112,14 @@ public void shouldNotReconnectWithoutBackoff() throws IOException, InterruptedEx final NoBackoffStrategy backoffStrategy = new NoBackoffStrategy(); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature("retries", BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Stream was closed"))); - - nakadiReader.runInternal(); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); + assertBackoffException(expectedException, 0, EOFException.class, "Stream was closed"); } @Test - public void shouldHandleBrokenInput() throws IOException, InterruptedException, BackoffException { + public void shouldHandleBrokenInput() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"".getBytes("utf-8")); when(response.getBody()).thenReturn(initialInputStream); @@ -134,16 +132,15 @@ public void shouldHandleBrokenInput() throws IOException, InterruptedException, final NoBackoffStrategy backoffStrategy = new NoBackoffStrategy(); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(instanceOf(JsonProcessingException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Unexpected end-of-input"))); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); - nakadiReader.runInternal(); + assertBackoffException(expectedException, 0, JsonProcessingException.class, "Unexpected end-of-input"); } @Test - public void shouldHandleBrokenInputInEvents() throws IOException, InterruptedException, BackoffException { + public void shouldHandleBrokenInputInEvents() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"123\",\"offset\":\"456\"},\"events\":[{\"id\":".getBytes("utf-8")); when(response.getBody()).thenReturn(initialInputStream); @@ -156,16 +153,15 @@ public void shouldHandleBrokenInputInEvents() throws IOException, InterruptedExc final NoBackoffStrategy backoffStrategy = new NoBackoffStrategy(); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(instanceOf(JsonProcessingException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Unexpected end-of-input"))); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); - nakadiReader.runInternal(); + assertBackoffException(expectedException, 0, JsonProcessingException.class, "Unexpected end-of-input"); } @Test - public void shouldRetryConnectionOnEof() throws IOException, InterruptedException, BackoffException { + public void shouldRetryConnectionOnEof() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"0\",\"offset\":\"0\"}}".getBytes("utf-8")); when(response.getBody()).thenReturn(initialInputStream); @@ -178,16 +174,15 @@ public void shouldRetryConnectionOnEof() throws IOException, InterruptedExceptio final ExponentialBackoffStrategy backoffStrategy = new EqualJitterBackoffStrategy(1, 1, 2, 1); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(1))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Reconnection failed"))); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); - nakadiReader.runInternal(); + assertBackoffException(expectedException, 1, IOException.class, "Reconnection failed"); } @Test - public void shouldRetryConnectionMultipleTimesOnEof() throws IOException, InterruptedException, BackoffException { + public void shouldRetryConnectionMultipleTimesOnEof() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"0\",\"offset\":\"0\"}}".getBytes("utf-8")); when(response.getBody()).thenReturn(initialInputStream); @@ -200,16 +195,14 @@ public void shouldRetryConnectionMultipleTimesOnEof() throws IOException, Interr final ExponentialBackoffStrategy backoffStrategy = new EqualJitterBackoffStrategy(1, 1, 2, 4); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(4))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Reconnection failed"))); - - nakadiReader.runInternal(); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); + assertBackoffException(expectedException, 4, IOException.class, "Reconnection failed"); } @Test - public void shouldRetryConnectionAfterExceptionDuringReconnection() throws IOException, InterruptedException, BackoffException { + public void shouldRetryConnectionAfterExceptionDuringReconnection() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"0\",\"offset\":\"0\"}}".getBytes("utf-8")); when(response.getBody()).thenReturn(initialInputStream); @@ -222,12 +215,11 @@ public void shouldRetryConnectionAfterExceptionDuringReconnection() throws IOExc final ExponentialBackoffStrategy backoffStrategy = new EqualJitterBackoffStrategy(1, 1, 2, 4); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(4))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Reconnection failed on second attempt"))); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); - nakadiReader.runInternal(); + assertBackoffException(expectedException, 4, IOException.class, "Reconnection failed on second attempt"); } static class InterruptibleInputStream extends InputStream { @@ -248,7 +240,7 @@ public int read() throws IOException { } @Test - public void shouldBeInterruptible() throws IOException, InterruptedException, BackoffException, ExecutionException, TimeoutException { + public void shouldBeInterruptible() throws IOException, InterruptedException, ExecutionException { final Response response = mock(Response.class); final InputStream endlessInputStream = new SequenceInputStream(new Enumeration() { @Override @@ -284,12 +276,12 @@ public InputStream nextElement() { nakadiReader.unchecked().run(); }); - Assert.assertNull("Thread should have completed normally", future.get()); + assertNull(future.get(),"Thread should have completed normally"); } - @Test(timeout = 2000) - public void shouldBeInterruptibleWhenReadingFromSocket() throws IOException, InterruptedException, BackoffException, ExecutionException, TimeoutException { + @Test + public void shouldBeInterruptibleWhenReadingFromSocket() throws IOException, InterruptedException, ExecutionException, TimeoutException { final Response response = mock(Response.class); final InetAddress loopbackAddress = InetAddress.getLoopbackAddress(); final ServerSocket serverSocket = new ServerSocket(0, 0, loopbackAddress); @@ -333,11 +325,11 @@ public void shouldBeInterruptibleWhenReadingFromSocket() throws IOException, Int nakadiReader.unchecked().run(); }); - Assert.assertNull("Thread should have completed normally", future.get(500, TimeUnit.MILLISECONDS)); + assertNull(future.get(500, TimeUnit.MILLISECONDS),"Thread should have completed normally"); } @Test - public void shouldReturnInsteadOfReconnectOnInterruption() throws IOException, InterruptedException, BackoffException, ExecutionException { + public void shouldReturnInsteadOfReconnectOnInterruption() throws IOException, InterruptedException, ExecutionException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"0\",\"offset\":\"0\"}}".getBytes("utf-8")); when(response.getBody()).thenAnswer(invocation -> { @@ -354,11 +346,11 @@ public void shouldReturnInsteadOfReconnectOnInterruption() throws IOException, I final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); final Future future = Executors.newCachedThreadPool().submit(nakadiReader.unchecked()); - Assert.assertNull("Thread should have completed normally", future.get()); + assertNull(future.get(), "Thread should have completed normally"); } @Test - public void shouldReturnOnInterruptionDuringReconnection() throws IOException, InterruptedException, BackoffException, ExecutionException { + public void shouldReturnOnInterruptionDuringReconnection() throws IOException, InterruptedException, ExecutionException { final Response initialResponse = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"0\",\"offset\":\"0\"}}".getBytes("utf-8")); when(initialResponse.getBody()).thenReturn(initialInputStream); @@ -379,11 +371,11 @@ public void shouldReturnOnInterruptionDuringReconnection() throws IOException, I final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); final Future future = Executors.newCachedThreadPool().submit(nakadiReader.unchecked()); - Assert.assertNull("Thread should have completed normally", future.get()); + assertNull(future.get(), "Thread should have completed normally"); } @Test - public void shouldProcessEventsAndCommitCursor() throws IOException, InterruptedException, BackoffException, EventAlreadyProcessedException { + public void shouldProcessEventsAndCommitCursor() throws IOException, EventAlreadyProcessedException { final Response response = mock(Response.class); String input = "{\"cursor\":{\"event_type\":\""+EVENT_NAME+"\",\"partition\":\"123\",\"offset\":\"456\"},\"events\":[{\"id\":\"789\"}]}"; final ByteArrayInputStream initialInputStream = new ByteArrayInputStream(input.getBytes("utf-8")); @@ -430,7 +422,7 @@ public void shouldProcessEventsAndCommitCursor() throws IOException, Interrupted } @Test - public void shouldFailWithoutCursors() throws IOException, InterruptedException, BackoffException, EventAlreadyProcessedException { + public void shouldFailWithoutCursors() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream inputStream = new ByteArrayInputStream("{\"foo\":\"bar\"}".getBytes("utf-8")); when(response.getBody()).thenReturn(inputStream); @@ -443,16 +435,15 @@ public void shouldFailWithoutCursors() throws IOException, InterruptedException, final NoBackoffStrategy backoffStrategy = new NoBackoffStrategy(); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Could not read cursor"))); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); - nakadiReader.runInternal(); + assertBackoffException(expectedException, 0, IOException.class, "Could not read cursor"); } @Test - public void shouldIgnoreMetadataInEventBatch() throws IOException, InterruptedException, BackoffException, EventAlreadyProcessedException { + public void shouldIgnoreMetadataInEventBatch() throws IOException, EventAlreadyProcessedException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"123\",\"offset\":\"456\"},\"events\":[{\"id\":\"789\"}],\"metadata\":{\"foo\":\"bar\"}}".getBytes("utf-8")); final ByteArrayInputStream emptyInputStream = new ByteArrayInputStream(new byte[0]); @@ -466,16 +457,15 @@ public void shouldIgnoreMetadataInEventBatch() throws IOException, InterruptedEx final NoBackoffStrategy backoffStrategy = new NoBackoffStrategy(); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Stream was closed"))); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); - nakadiReader.runInternal(); + assertBackoffException(expectedException, 0, IOException.class, "Stream was closed"); } @Test - public void shouldIgnoreAdditionalPropertiesInEventBatch() throws IOException, InterruptedException, BackoffException, EventAlreadyProcessedException { + public void shouldIgnoreAdditionalPropertiesInEventBatch() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"123\",\"offset\":\"456\"},\"foo\":\"bar\",\"events\":[{\"id\":\"789\"}],\"metadata\":{\"foo\":\"bar\"}}".getBytes("utf-8")); final ByteArrayInputStream emptyInputStream = new ByteArrayInputStream(new byte[0]); @@ -489,16 +479,14 @@ public void shouldIgnoreAdditionalPropertiesInEventBatch() throws IOException, I final NoBackoffStrategy backoffStrategy = new NoBackoffStrategy(); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Stream was closed"))); - - nakadiReader.runInternal(); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); + assertBackoffException(expectedException, 0, IOException.class, "Stream was closed"); } @Test - public void shouldIgnoreAdditionalPropertiesInEventBatchInAnyOrder() throws IOException, InterruptedException, BackoffException, EventAlreadyProcessedException { + public void shouldIgnoreAdditionalPropertiesInEventBatchInAnyOrder() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"foo\":\"bar\",\"cursor\":{\"partition\":\"123\",\"offset\":\"456\"},\"events\":[{\"id\":\"789\"}],\"baz\":123}".getBytes("utf-8")); final ByteArrayInputStream emptyInputStream = new ByteArrayInputStream(new byte[0]); @@ -512,16 +500,15 @@ public void shouldIgnoreAdditionalPropertiesInEventBatchInAnyOrder() throws IOEx final NoBackoffStrategy backoffStrategy = new NoBackoffStrategy(); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), SomeEvent.class, listener); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Stream was closed"))); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); - nakadiReader.runInternal(); + assertBackoffException(expectedException, 0, IOException.class, "Stream was closed"); } @Test - public void shouldExtractPropertyFromEvents() throws IOException, InterruptedException, BackoffException, EventAlreadyProcessedException { + public void shouldExtractPropertyFromEvents() throws IOException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"0\",\"offset\":\"0\"},\"events\":[{\"id\":\"1\",\"foo\":\"bar\"},{\"foo\":\"bar\",\"id\":\"2\"},{\"foo\":[\"bar\"],\"id\":\"3\",\"baz\":{\"id\":\"xyz\"}},{}]}".getBytes("utf-8")); final ByteArrayInputStream emptyInputStream = new ByteArrayInputStream(new byte[0]); @@ -538,18 +525,16 @@ public void shouldExtractPropertyFromEvents() throws IOException, InterruptedExc final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), new StringPropertyExtractingEventReader("id"), ids::addAll, DefaultBatchHandler.INSTANCE, NoMetricsCollector.NO_METRICS_COLLECTOR); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Stream was closed"))); - - nakadiReader.runInternal(); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); + assertBackoffException(expectedException, 0, IOException.class, "Stream was closed"); assertEquals(asList("1", "2", "3"), ids); } @Test - public void shouldExtractPropertyFromEmptyEvents() throws IOException, InterruptedException, BackoffException, EventAlreadyProcessedException { + public void shouldExtractPropertyFromEmptyEvents() throws IOException, EventAlreadyProcessedException { final Response response = mock(Response.class); final ByteArrayInputStream initialInputStream = new ByteArrayInputStream("{\"cursor\":{\"partition\":\"0\",\"offset\":\"0\"},\"events\":[]}".getBytes("utf-8")); final ByteArrayInputStream emptyInputStream = new ByteArrayInputStream(new byte[0]); @@ -566,13 +551,11 @@ public void shouldExtractPropertyFromEmptyEvents() throws IOException, Interrupt final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.empty(), new StringPropertyExtractingEventReader("id"), ids::addAll, DefaultBatchHandler.INSTANCE, NoMetricsCollector.NO_METRICS_COLLECTOR); - expectedException.expect(BackoffException.class); - expectedException.expect(ComposeMatchers.hasFeature(BackoffException::getRetries, equalTo(0))); - expectedException.expectCause(instanceOf(IOException.class)); - expectedException.expectCause(ComposeMatchers.hasFeature("message", Exception::getMessage, Matchers.containsString("Stream was closed"))); - - nakadiReader.runInternal(); + BackoffException expectedException = assertThrows(BackoffException.class, () -> { + nakadiReader.runInternal(); + }); + assertBackoffException(expectedException, 0, IOException.class, "Stream was closed"); assertEquals(emptyList(), ids); } @@ -592,12 +575,12 @@ public void shouldSendCursorsForLockedPartitions() throws IOException { final Lock lock = new Lock(EVENT_NAME, "test", asList(new Partition("0", "0", "100"), new Partition("1", "0", "100"))); final NakadiReader nakadiReader = new NakadiReader<>(uri, RequestFactory, backoffStrategy, cursorManager, objectMapper, Collections.singleton(EVENT_NAME), Optional.empty(), Optional.of(lock), SomeEvent.class, listener); - expectedException.expect(IOException.class); - expectedException.expectMessage(equalTo("Initial connection failed")); - - nakadiReader.run(); + IOException expectedException = assertThrows(IOException.class, () -> { + nakadiReader.run(); + }); - assertEquals(singletonList("[{\"partition\":\"0\",\"offset\":\"0\"},{\"partition\":\"1\",\"offset\":\"10\"}"), headers.get("X-Nakadi-Cursors")); + assertThat(expectedException.getMessage(), equalTo("Initial connection failed")); + assertEquals(singletonList("[{\"partition\":\"0\",\"offset\":\"0\"},{\"partition\":\"1\",\"offset\":\"10\"}]"), headers.get("X-Nakadi-Cursors")); } @Test @@ -662,8 +645,8 @@ public void shouldCloseOnRuntimeException() throws IOException { } } - @Test(timeout = 2000) - public void shouldStopAndResumeReading() throws IOException, InterruptedException, BackoffException, ExecutionException, TimeoutException, EventAlreadyProcessedException { + @Test + public void shouldStopAndResumeReading() throws IOException, InterruptedException, EventAlreadyProcessedException { final InetAddress loopbackAddress = InetAddress.getLoopbackAddress(); final ServerSocket serverSocket = new ServerSocket(0, 0, loopbackAddress); final ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 8, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); @@ -720,24 +703,31 @@ public void shouldStopAndResumeReading() throws IOException, InterruptedExceptio final Future future = executor.submit(runnable::run); Thread.sleep(200); - Assert.assertEquals(3, executor.getActiveCount()); + assertEquals(3, executor.getActiveCount()); future.cancel(true); - Assert.assertTrue("Future should be canceled", future.isCancelled()); - Assert.assertTrue("Future should be done", future.isDone()); + assertThat("Future should be canceled", future.isCancelled()); + assertThat("Future should be done", future.isDone()); Thread.sleep(200); - Assert.assertEquals(1, executor.getActiveCount()); + assertEquals(1, executor.getActiveCount()); final Future future2 = executor.submit(runnable); Thread.sleep(200); - Assert.assertEquals(3, executor.getActiveCount()); + assertEquals(3, executor.getActiveCount()); future2.cancel(true); - Assert.assertTrue("Future should be canceled", future2.isCancelled()); - Assert.assertTrue("Future should be done", future2.isDone()); + assertThat("Future should be canceled", future2.isCancelled()); + assertThat("Future should be done", future2.isDone()); Thread.sleep(200); - Assert.assertEquals(1, executor.getActiveCount()); + assertEquals(1, executor.getActiveCount()); verify(listener, times(2)).accept(anyList()); } + private void assertBackoffException(BackoffException expectedException, int retries, Class cause, String errorMessage) { + assertAll("expectedException", + () -> assertThat(expectedException.getRetries(), is(retries)), + () -> assertThat(expectedException.getCause(), instanceOf(cause)), + () -> assertThat(expectedException.getCause().getMessage(), containsString(errorMessage))); + } + } diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/ProblemHandlingRequestTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/ProblemHandlingRequestTest.java index c000e20f..e7b1f50c 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/ProblemHandlingRequestTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/ProblemHandlingRequestTest.java @@ -1,8 +1,6 @@ package org.zalando.fahrschein; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.zalando.fahrschein.http.api.ContentType; import org.zalando.fahrschein.http.api.Headers; @@ -16,16 +14,13 @@ import java.nio.charset.StandardCharsets; import java.util.Optional; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.instanceOf; -import static org.hobsoft.hamcrest.compose.ComposeMatchers.hasFeature; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.when; public class ProblemHandlingRequestTest { - @Rule - public final ExpectedException expectedException = ExpectedException.none(); - private final Request request = Mockito.mock(Request.class); private final Response response = Mockito.mock(Response.class); private final ProblemHandlingRequest problemHandlingRequest = new ProblemHandlingRequest(request); @@ -42,13 +37,14 @@ public void shouldCreateProblemWhenTypeIsMissing() throws IOException { when(request.execute()).thenReturn(response); - expectedException.expect(instanceOf(IOProblem.class)); - expectedException.expect(hasFeature("status code", IOProblem::getStatusCode, equalTo(422))); - expectedException.expect(hasFeature("type", IOProblem::getType, equalTo(URI.create("about:blank")))); - expectedException.expect(hasFeature("title", IOProblem::getTitle, equalTo("Unprocessable Entity"))); - expectedException.expect(hasFeature("detail", IOProblem::getDetail, equalTo(Optional.of("Session with stream id not found")))); + IOProblem expectedException = assertThrows(IOProblem.class, () -> { + problemHandlingRequest.execute(); + }); - problemHandlingRequest.execute(); + assertThat(expectedException.getStatusCode(), equalTo(422)); + assertThat(expectedException.getType(), equalTo(URI.create("about:blank"))); + assertThat(expectedException.getTitle(), equalTo("Unprocessable Entity")); + assertThat(expectedException.getDetail(), equalTo(Optional.of("Session with stream id not found"))); } @Test @@ -62,13 +58,14 @@ public void shouldCreateProblemFromStatusAndText() throws IOException { when(request.execute()).thenReturn(response); - expectedException.expect(instanceOf(IOProblem.class)); - expectedException.expect(hasFeature("status code", IOProblem::getStatusCode, equalTo(409))); - expectedException.expect(hasFeature("type", IOProblem::getType, equalTo(URI.create("about:blank")))); - expectedException.expect(hasFeature("title", IOProblem::getTitle, equalTo("conflict"))); - expectedException.expect(hasFeature("detail", IOProblem::getDetail, equalTo(Optional.empty()))); + IOProblem expectedException = assertThrows(IOProblem.class, () -> { + problemHandlingRequest.execute(); + }); - problemHandlingRequest.execute(); + assertThat(expectedException.getStatusCode(), equalTo(409)); + assertThat(expectedException.getType(), equalTo(URI.create("about:blank"))); + assertThat(expectedException.getTitle(), equalTo("conflict")); + assertThat(expectedException.getDetail(), equalTo(Optional.empty())); } @Test @@ -83,13 +80,15 @@ public void shouldDeserializeProblemJson() throws IOException { when(request.execute()).thenReturn(response); - expectedException.expect(instanceOf(IOProblem.class)); - expectedException.expect(hasFeature("status code", IOProblem::getStatusCode, equalTo(404))); - expectedException.expect(hasFeature("type", IOProblem::getType, equalTo(URI.create("http://httpstatus.es/404")))); - expectedException.expect(hasFeature("title", IOProblem::getTitle, equalTo("Not Found"))); - expectedException.expect(hasFeature("detail", IOProblem::getDetail, equalTo(Optional.of("EventType does not exist.")))); + IOProblem expectedException = assertThrows(IOProblem.class, () -> { + problemHandlingRequest.execute(); + }); + + assertThat(expectedException.getStatusCode(), equalTo(404)); + assertThat(expectedException.getType(), equalTo(URI.create("http://httpstatus.es/404"))); + assertThat(expectedException.getTitle(), equalTo("Not Found")); + assertThat(expectedException.getDetail(), equalTo(Optional.of("EventType does not exist."))); - problemHandlingRequest.execute(); } @Test @@ -104,13 +103,13 @@ public void shouldDeserializeOAuthError() throws IOException { when(request.execute()).thenReturn(response); - expectedException.expect(instanceOf(IOProblem.class)); - expectedException.expect(hasFeature("status code", IOProblem::getStatusCode, equalTo(400))); - expectedException.expect(hasFeature("type", IOProblem::getType, equalTo(URI.create("about:blank")))); - expectedException.expect(hasFeature("title", IOProblem::getTitle, equalTo("invalid_request"))); - expectedException.expect(hasFeature("detail", IOProblem::getDetail, equalTo(Optional.of("Access Token not valid")))); - - problemHandlingRequest.execute(); + IOProblem expectedException = assertThrows(IOProblem.class, () -> { + problemHandlingRequest.execute(); + }); + assertThat(expectedException.getStatusCode(), equalTo(400)); + assertThat(expectedException.getType(), equalTo(URI.create("about:blank"))); + assertThat(expectedException.getTitle(), equalTo("invalid_request")); + assertThat(expectedException.getDetail(), equalTo(Optional.of("Access Token not valid"))); } @@ -126,9 +125,9 @@ public void shouldHandleMultiStatus() throws IOException { when(request.execute()).thenReturn(response); - expectedException.expect(instanceOf(EventPublishingException.class)); - - problemHandlingRequest.execute(); + assertThrows(EventPublishingException.class, () -> { + problemHandlingRequest.execute(); + }); } } diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/StreamParametersTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/StreamParametersTest.java index 1a7f90b4..3f91c423 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/StreamParametersTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/StreamParametersTest.java @@ -1,18 +1,16 @@ package org.zalando.fahrschein; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; +import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.arrayContainingInAnyOrder; +import static org.hamcrest.Matchers.is; import static org.hamcrest.collection.IsArrayWithSize.arrayWithSize; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; public class StreamParametersTest { - @Rule - public ExpectedException expectedEx = ExpectedException.none(); - @Test public void createsAValidQueryParamString() throws IllegalArgumentException { final StreamParameters streamParameters = new StreamParameters() @@ -43,34 +41,36 @@ public void createsAValidQueryParamString() throws IllegalArgumentException { @Test public void streamParametersWithStreamTimeoutFailure() throws IllegalArgumentException { - expectedEx.expect(IllegalArgumentException.class); - expectedEx.expectMessage("stream_timeout is lower than batch_flush_timeout."); - final StreamParameters streamParameters = new StreamParameters() - .withBatchFlushTimeout(100) - .withStreamTimeout(50); + IllegalArgumentException expectedException = assertThrows(IllegalArgumentException.class, () -> { + final StreamParameters streamParameters = new StreamParameters() + .withBatchFlushTimeout(100) + .withStreamTimeout(50); + }); + + assertThat(expectedException.getMessage(), is("stream_timeout is lower than batch_flush_timeout.")); } @Test - public void streamParametersWithStreamLimitFailure() throws IllegalArgumentException { - - expectedEx.expect(IllegalArgumentException.class); - expectedEx.expectMessage("streamLimit is lower than batch_limit."); - - final StreamParameters streamParameters = new StreamParameters() - .withBatchLimit(20) - .withStreamLimit(10); + public void streamParametersWithStreamLimitFailure() { + + IllegalArgumentException expectedException = assertThrows(IllegalArgumentException.class, () -> { + new StreamParameters() + .withBatchLimit(20) + .withStreamLimit(10); + }); + assertThat(expectedException.getMessage(), is("streamLimit is lower than batch_limit.")); } @Test public void streamParametersWithBatchLimitZero() throws IllegalArgumentException { + IllegalArgumentException expectedException = assertThrows(IllegalArgumentException.class, () -> { + new StreamParameters() + .withBatchLimit(0) + .withStreamLimit(10); + }); - expectedEx.expect(IllegalArgumentException.class); - expectedEx.expectMessage("batch_limit can't be lower than 1."); - - final StreamParameters streamParameters = new StreamParameters() - .withBatchLimit(0) - .withStreamLimit(10); + assertThat(expectedException.getMessage(), is("batch_limit can't be lower than 1.")); } } \ No newline at end of file diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/domain/CursorTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/domain/CursorTest.java index 43bcf1b5..b25ff8c8 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/domain/CursorTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/domain/CursorTest.java @@ -1,8 +1,6 @@ package org.zalando.fahrschein.domain; -import org.hamcrest.core.IsEqual; -import org.hamcrest.core.IsNot; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.IsEqual.equalTo; diff --git a/fahrschein/src/test/java/org/zalando/fahrschein/domain/MetadataTest.java b/fahrschein/src/test/java/org/zalando/fahrschein/domain/MetadataTest.java index 735ef43a..8fe68663 100644 --- a/fahrschein/src/test/java/org/zalando/fahrschein/domain/MetadataTest.java +++ b/fahrschein/src/test/java/org/zalando/fahrschein/domain/MetadataTest.java @@ -1,12 +1,13 @@ package org.zalando.fahrschein.domain; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; import java.time.OffsetDateTime; import java.util.Collections; import java.util.UUID; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class MetadataTest { @Test @@ -22,13 +23,13 @@ public void shouldHaveCleanStringRepresentation() { final Metadata metadata = new Metadata(eventType, eid, occurredAt, partition, version, publishedBy, receivedAt, flowId, Collections.emptyMap()); - Assert.assertTrue(metadata.toString().contains(metadata.getEventType())); - Assert.assertTrue(metadata.toString().contains(metadata.getEid())); - Assert.assertTrue(metadata.toString().contains(metadata.getOccurredAt().toString())); - Assert.assertTrue(metadata.toString().contains(metadata.getPartition())); - Assert.assertTrue(metadata.toString().contains(metadata.getVersion())); - Assert.assertTrue(metadata.toString().contains(metadata.getPublishedBy())); - Assert.assertTrue(metadata.toString().contains(metadata.getReceivedAt().toString())); - Assert.assertTrue(metadata.toString().contains(metadata.getFlowId())); + assertTrue(metadata.toString().contains(metadata.getEventType())); + assertTrue(metadata.toString().contains(metadata.getEid())); + assertTrue(metadata.toString().contains(metadata.getOccurredAt().toString())); + assertTrue(metadata.toString().contains(metadata.getPartition())); + assertTrue(metadata.toString().contains(metadata.getVersion())); + assertTrue(metadata.toString().contains(metadata.getPublishedBy())); + assertTrue(metadata.toString().contains(metadata.getReceivedAt().toString())); + assertTrue(metadata.toString().contains(metadata.getFlowId())); } } diff --git a/gradle.properties b/gradle.properties index 7ab96cb2..358764a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ jackson.version=2.13.3 slf4j.version=1.7.25 spring.version=5.3.20 mockito.version=4.3.1 -junit.version=4.13.1 +junit.version=5.8.2 testContainersV=1.16.2 okhttp.version=4.9.3 apachehttp.version=4.5.13