diff --git a/README.md b/README.md index cd4ca9be..338d5635 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,8 @@ Jetty | Jetty Server. JGit | Basic usages of [JGit][jgit]. JMH | Java Microbenchmark Harness (JMH). JSON | JSON conversion libraries in Java. -JUnit | JUnit testing framework. +JUnit 4 | JUnit 4 testing framework. +JUnit 5 | JUnit 5 testing framework. Logback | [Logback](http://logback.qos.ch/) logging framework. Maven | Basic functionality of Maven. Mongo | The MongoDB database diff --git a/junit5/pom.xml b/junit5/pom.xml new file mode 100644 index 00000000..3bcda980 --- /dev/null +++ b/junit5/pom.xml @@ -0,0 +1,37 @@ + + + + java-examples-parent + io.mincong + 1.0.0-SNAPSHOT + + 4.0.0 + + java-examples-junit5 + Java Examples - JUnit 5 + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.assertj + assertj-core + test + + + \ No newline at end of file diff --git a/junit5/src/main/java/io/mincong/junit5/ChatBot.java b/junit5/src/main/java/io/mincong/junit5/ChatBot.java new file mode 100644 index 00000000..ac958669 --- /dev/null +++ b/junit5/src/main/java/io/mincong/junit5/ChatBot.java @@ -0,0 +1,5 @@ +package io.mincong.junit5; + +public interface ChatBot { + String sayHello(String username); +} diff --git a/junit5/src/main/java/io/mincong/junit5/StringConcatenationChatBot.java b/junit5/src/main/java/io/mincong/junit5/StringConcatenationChatBot.java new file mode 100644 index 00000000..bfee123c --- /dev/null +++ b/junit5/src/main/java/io/mincong/junit5/StringConcatenationChatBot.java @@ -0,0 +1,19 @@ +package io.mincong.junit5; + +public class StringConcatenationChatBot implements ChatBot { + + @Override + public String sayHello(String username) { + return "Hello, " + username; + } + + /** + * In IntelliJ IDEA, run ChatBotTest with coverage and observe the test coverage here. You can see + * that this test is not tested. One advantage of using parameterized testing is that it can + * increase the test coverage easily with difference scenarios. + */ + @SuppressWarnings("unused") + public String sayNo(String username) { + return "No, " + username; + } +} diff --git a/junit5/src/main/java/io/mincong/junit5/StringFormatChatBot.java b/junit5/src/main/java/io/mincong/junit5/StringFormatChatBot.java new file mode 100644 index 00000000..91c25e68 --- /dev/null +++ b/junit5/src/main/java/io/mincong/junit5/StringFormatChatBot.java @@ -0,0 +1,8 @@ +package io.mincong.junit5; + +public class StringFormatChatBot implements ChatBot { + @Override + public String sayHello(String username) { + return String.format("Hello, %s", username); + } +} diff --git a/junit5/src/test/java/io/mincong/junit5/ChatBotTest.java b/junit5/src/test/java/io/mincong/junit5/ChatBotTest.java new file mode 100644 index 00000000..20d40d15 --- /dev/null +++ b/junit5/src/test/java/io/mincong/junit5/ChatBotTest.java @@ -0,0 +1,39 @@ +package io.mincong.junit5; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.stream.Stream; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.ArgumentsProvider; +import org.junit.jupiter.params.provider.ArgumentsSource; + +class ChatBotTest { + /** + * Use annotation {@link ParameterizedTest} to test multiple implementation of {@link ChatBot}. It + * ensures that all implementations respect the specification of the interface and returns the + * expected results regardless the internal implementation. + * + * @param bot the chat bot to test + */ + @ParameterizedTest + @ArgumentsSource(ChatBotProvider.class) + void sayHello(ChatBot bot) { + assertThat(bot.sayHello("Foo")).isEqualTo("Hello, Foo"); + assertThat(bot.sayHello("Bar")).isEqualTo("Hello, Bar"); + } + + public static class ChatBotProvider implements ArgumentsProvider { + + /** + * This method creates multiple chat bot instances using different implementations and returns + * them as a stream of arguments for the parameterized test. + */ + @Override + public Stream provideArguments(ExtensionContext context) { + return Stream.of(new StringFormatChatBot(), new StringConcatenationChatBot()) + .map(Arguments::of); + } + } +} diff --git a/junit5/src/test/java/io/mincong/junit5/MathTest.java b/junit5/src/test/java/io/mincong/junit5/MathTest.java new file mode 100644 index 00000000..0d3e2582 --- /dev/null +++ b/junit5/src/test/java/io/mincong/junit5/MathTest.java @@ -0,0 +1,18 @@ +package io.mincong.junit5; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +public class MathTest { + @ParameterizedTest + @CsvSource({ + "1, 2, 2", + "1, -1, 1", + "1, 1, 1", + }) + void testMax(int a, int b, int max) { + assertThat(Math.max(a, b)).isEqualTo(max); + } +} diff --git a/pom.xml b/pom.xml index 9dba8671..c52cdf1c 100644 --- a/pom.xml +++ b/pom.xml @@ -61,6 +61,7 @@ jetty protobuf reliability + junit5