mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-09-26 23:45:47 +00:00
JUnit 5 extension for testing mvnd
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
package org.jboss.fuse.mvnd.assertj;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
|
||||
/**
|
||||
* An AssertJ {@link Condition} to assert that each item of a collection of regular expressions matches some item in
|
||||
* a list of strings exactly once in the order given by the pattern collection. The input list may contain other
|
||||
* non-matching items.
|
||||
*
|
||||
* @param <T> the type of the tested {@link List}.
|
||||
*/
|
||||
public class MatchInOrderAmongOthers<T extends List<? extends String>> extends Condition<T> {
|
||||
|
||||
public MatchInOrderAmongOthers(String... expectedItems) {
|
||||
this(Stream.of(expectedItems).map(Pattern::compile).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public MatchInOrderAmongOthers(final Collection<Pattern> patterns) {
|
||||
super(
|
||||
messages -> messages.stream()
|
||||
/* map each message to the matching pattern or null of none matches */
|
||||
.map(m -> patterns.stream()
|
||||
.filter(pat -> pat.matcher(m).find())
|
||||
.findFirst()
|
||||
.orElse(null))
|
||||
.filter(pat -> pat != null) /* remove null patterns */
|
||||
.collect(Collectors.toList())
|
||||
/* if the mapped patterns equal the input patterns then each pattern matched exactly once */
|
||||
.equals(patterns),
|
||||
"Match in order: " + patterns.stream().map(Pattern::pattern).collect(Collectors.joining(", ")),
|
||||
patterns);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package org.jboss.fuse.mvnd.it;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||
|
||||
public class MvndTestUtil {
|
||||
|
||||
private MvndTestUtil() {
|
||||
}
|
||||
|
||||
public static String plugin(Properties props, String artifactId) {
|
||||
return artifactId + ":" + props.getProperty(artifactId + ".version");
|
||||
}
|
||||
|
||||
public static Properties properties(Path pomXmlPath) {
|
||||
try (Reader runtimeReader = Files.newBufferedReader(pomXmlPath, StandardCharsets.UTF_8)) {
|
||||
final MavenXpp3Reader rxppReader = new MavenXpp3Reader();
|
||||
return rxppReader.read(runtimeReader).getProperties();
|
||||
} catch (IOException | XmlPullParserException e) {
|
||||
throw new RuntimeException("Could not read or parse " + pomXmlPath);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
package org.jboss.fuse.mvnd.it;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.MatchInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.daemon.Client;
|
||||
import org.jboss.fuse.mvnd.daemon.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.daemon.Layout;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MvndTest(projectDir = "src/test/projects/single-module")
|
||||
public class SingleModuleTest {
|
||||
|
||||
@Inject
|
||||
Client client;
|
||||
|
||||
@Inject
|
||||
Layout layout;
|
||||
|
||||
@Test
|
||||
void cleanTest() throws IOException {
|
||||
final Path helloFilePath = layout.multiModuleProjectDirectory().resolve("target/hello.txt");
|
||||
if (Files.exists(helloFilePath)) {
|
||||
Files.delete(helloFilePath);
|
||||
}
|
||||
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
client.execute(output, "clean", "test").assertSuccess();
|
||||
|
||||
final ArgumentCaptor<String> logMessage = ArgumentCaptor.forClass(String.class);
|
||||
Mockito.verify(output, Mockito.atLeast(1)).log(logMessage.capture());
|
||||
Assertions.assertThat(logMessage.getAllValues())
|
||||
.is(new MatchInOrderAmongOthers<>(
|
||||
"Building single-module",
|
||||
"maven-clean-plugin:[^:]+:clean",
|
||||
"maven-compiler-plugin:[^:]+:compile",
|
||||
"maven-compiler-plugin:[^:]+:testCompile",
|
||||
"maven-surefire-plugin:[^:]+:test",
|
||||
"SUCCESS build of project org.jboss.fuse.mvnd.test.single-module:single-module"));
|
||||
|
||||
final Properties props = MvndTestUtil.properties(layout.multiModuleProjectDirectory().resolve("pom.xml"));
|
||||
|
||||
final InOrder inOrder = Mockito.inOrder(output);
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-clean-plugin")
|
||||
+ ":clean {execution: default-clean}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-resources-plugin")
|
||||
+ ":resources {execution: default-resources}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-compiler-plugin")
|
||||
+ ":compile {execution: default-compile}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-resources-plugin")
|
||||
+ ":testResources {execution: default-testResources}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-compiler-plugin")
|
||||
+ ":testCompile {execution: default-testCompile}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module:org.apache.maven.plugins:" + MvndTestUtil.plugin(props, "maven-surefire-plugin")
|
||||
+ ":test {execution: default-test}");
|
||||
inOrder.verify(output).projectStateChanged(
|
||||
"single-module",
|
||||
":single-module");
|
||||
|
||||
inOrder.verify(output).projectFinished("single-module");
|
||||
|
||||
/* The target/hello.txt is created by HelloTest */
|
||||
Assertions.assertThat(helloFilePath).exists();
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
package org.jboss.fuse.mvnd.it;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.jboss.fuse.mvnd.assertj.MatchInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.daemon.Client;
|
||||
import org.jboss.fuse.mvnd.daemon.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.daemon.DaemonInfo;
|
||||
import org.jboss.fuse.mvnd.daemon.DaemonRegistry;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MvndTest(projectDir = "src/test/projects/single-module")
|
||||
public class StopStatusTest {
|
||||
|
||||
@Inject
|
||||
Client client;
|
||||
|
||||
@Inject
|
||||
DaemonRegistry registry;
|
||||
|
||||
@Test
|
||||
void stopStatus() throws IOException {
|
||||
|
||||
/* The registry should be empty before we run anything */
|
||||
Assertions.assertThat(registry.getAll()).isEmpty();
|
||||
|
||||
client.execute(Mockito.mock(ClientOutput.class), "clean").assertSuccess();
|
||||
/* There should be exactly one item in the registry after the first build */
|
||||
Assertions.assertThat(registry.getAll().size()).isEqualTo(1);
|
||||
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
client.execute(output, "--status").assertSuccess();
|
||||
final DaemonInfo d = registry.getAll().get(0);
|
||||
final ArgumentCaptor<String> logMessage = ArgumentCaptor.forClass(String.class);
|
||||
Mockito.verify(output, Mockito.atLeast(1)).log(logMessage.capture());
|
||||
Assertions.assertThat(logMessage.getAllValues())
|
||||
.is(new MatchInOrderAmongOthers<>(
|
||||
d.getUid() + " +" + d.getPid() + " +" + d.getAddress() + " +" + d.getState()));
|
||||
|
||||
client.execute(Mockito.mock(ClientOutput.class), "clean").assertSuccess();
|
||||
/* There should still be exactly one item in the registry after the second build */
|
||||
Assertions.assertThat(registry.getAll().size()).isEqualTo(1);
|
||||
|
||||
client.execute(Mockito.mock(ClientOutput.class), "--stop").assertSuccess();
|
||||
/* No items in the registry after we have killed all daemons */
|
||||
Assertions.assertThat(registry.getAll()).isEmpty();
|
||||
}
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
package org.jboss.fuse.mvnd.it;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.jboss.fuse.mvnd.assertj.MatchInOrderAmongOthers;
|
||||
import org.jboss.fuse.mvnd.daemon.Client;
|
||||
import org.jboss.fuse.mvnd.daemon.ClientOutput;
|
||||
import org.jboss.fuse.mvnd.junit.MvndTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
@MvndTest(projectDir = "src/test/projects/single-module")
|
||||
public class VersionTest {
|
||||
|
||||
@Inject
|
||||
Client client;
|
||||
|
||||
@Test
|
||||
void version() throws IOException {
|
||||
final ClientOutput output = Mockito.mock(ClientOutput.class);
|
||||
|
||||
client.execute(output, "-v").assertSuccess();
|
||||
|
||||
final ArgumentCaptor<String> logMessage = ArgumentCaptor.forClass(String.class);
|
||||
Mockito.verify(output, Mockito.atLeast(1)).log(logMessage.capture());
|
||||
|
||||
Assertions.assertThat(logMessage.getAllValues())
|
||||
.is(new MatchInOrderAmongOthers<>("Maven Daemon " + System.getProperty("project.version")));
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package org.jboss.fuse.mvnd.junit;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
@ExtendWith(MvndTestExtension.class)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface MvndTest {
|
||||
/**
|
||||
* The path to the root directory of a test project relative to the current maven module directory. E.g.
|
||||
* <code>@MvndTest(projectDir = "src/test/projects/my-project")</code>
|
||||
*/
|
||||
String projectDir();
|
||||
}
|
@@ -0,0 +1,153 @@
|
||||
package org.jboss.fuse.mvnd.junit;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jboss.fuse.mvnd.daemon.Client;
|
||||
import org.jboss.fuse.mvnd.daemon.DaemonInfo;
|
||||
import org.jboss.fuse.mvnd.daemon.DaemonRegistry;
|
||||
import org.jboss.fuse.mvnd.daemon.Layout;
|
||||
import org.jboss.fuse.mvnd.jpm.ProcessImpl;
|
||||
import org.junit.jupiter.api.extension.AfterAllCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeAllCallback;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||
|
||||
public class MvndTestExtension implements BeforeAllCallback, BeforeEachCallback, AfterAllCallback {
|
||||
|
||||
private volatile Exception bootException;
|
||||
public MvndTestExtension() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeAll(ExtensionContext context) throws Exception {
|
||||
try {
|
||||
final Store store = context.getRoot().getStore(ExtensionContext.Namespace.GLOBAL);
|
||||
final Class<?> testClass = context.getRequiredTestClass();
|
||||
final MvndTest mnvdTest = testClass.getAnnotation(MvndTest.class);
|
||||
store.put(MvndResource.class.getName(), MvndResource.create(context.getRequiredTestClass().getSimpleName(), mnvdTest.projectDir()));
|
||||
} catch (Exception e) {
|
||||
this.bootException = e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeEach(ExtensionContext context) throws Exception {
|
||||
if (bootException != null) {
|
||||
throw new Exception("Could not init " + context.getRequiredTestClass(), bootException);
|
||||
}
|
||||
final Store store = context.getRoot().getStore(ExtensionContext.Namespace.GLOBAL);
|
||||
final MvndResource resource = (MvndResource) store.get(MvndResource.class.getName());
|
||||
|
||||
final Object testInstance = context.getRequiredTestInstance();
|
||||
Class<?> c = testInstance.getClass();
|
||||
while (c != Object.class) {
|
||||
for (Field f : c.getDeclaredFields()) {
|
||||
javax.inject.Inject inject = f.getAnnotation(javax.inject.Inject.class);
|
||||
if (inject != null) {
|
||||
f.setAccessible(true);
|
||||
if (f.getType() == DaemonRegistry.class) {
|
||||
f.set(testInstance, resource.registry);
|
||||
} else if (f.getType() == Layout.class) {
|
||||
f.set(testInstance, resource.layout);
|
||||
} else if (f.getType() == Client.class) {
|
||||
f.set(testInstance, new Client(resource.layout));
|
||||
}
|
||||
}
|
||||
}
|
||||
c = c.getSuperclass();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAll(ExtensionContext context) throws Exception {
|
||||
final Store store = context.getRoot().getStore(ExtensionContext.Namespace.GLOBAL);
|
||||
final MvndResource resource = (MvndResource) store.remove(MvndResource.class.getName());
|
||||
if (resource != null) {
|
||||
resource.close();
|
||||
}
|
||||
}
|
||||
|
||||
static class MvndResource implements ExtensionContext.Store.CloseableResource {
|
||||
|
||||
private final Layout layout;
|
||||
private final DaemonRegistry registry;
|
||||
|
||||
public static MvndResource create(String className, String rawProjectDir) throws IOException {
|
||||
if (rawProjectDir == null) {
|
||||
throw new IllegalStateException("rawProjectDir of @MvndTest must be set");
|
||||
}
|
||||
final Path mvndTestSrcDir = Paths.get(rawProjectDir).toAbsolutePath().normalize();
|
||||
if (!Files.exists(mvndTestSrcDir)) {
|
||||
throw new IllegalStateException("@MvndTest(projectDir = \""+ rawProjectDir +"\") points at a path that does not exist: " + mvndTestSrcDir);
|
||||
}
|
||||
|
||||
final Path testDir = Paths.get("target/mvnd-tests/" + className).toAbsolutePath();
|
||||
try (Stream<Path> files = Files.walk(mvndTestSrcDir)) {
|
||||
files.forEach(source -> {
|
||||
final Path dest = testDir.resolve(mvndTestSrcDir.relativize(source));
|
||||
try {
|
||||
if (Files.isDirectory(source)) {
|
||||
Files.createDirectories(dest);
|
||||
} else {
|
||||
Files.createDirectories(dest.getParent());
|
||||
Files.copy(source, dest);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final Path mvndHome = Paths.get(Objects.requireNonNull(System.getProperty("mvnd.home"), "System property mvnd.home must be set")).normalize().toAbsolutePath();
|
||||
if (!Files.isDirectory(mvndHome)) {
|
||||
throw new IllegalStateException("The value of mvnd.home system property points at a path that does not exist or is not a directory");
|
||||
}
|
||||
final Layout layout = new Layout(Paths.get(System.getProperty("java.home")).toAbsolutePath().normalize(),
|
||||
mvndHome,
|
||||
testDir,
|
||||
testDir);
|
||||
final DaemonRegistry registry = new DaemonRegistry(layout.registry());
|
||||
return new MvndResource(layout, registry);
|
||||
}
|
||||
|
||||
public MvndResource(Layout layout, DaemonRegistry registry) {
|
||||
super();
|
||||
this.layout = layout;
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception {
|
||||
List<DaemonInfo> daemons;
|
||||
final int timeout = 5000;
|
||||
final long deadline = System.currentTimeMillis() + timeout;
|
||||
while (!(daemons = registry.getAll()).isEmpty()) {
|
||||
for (DaemonInfo di : daemons) {
|
||||
try {
|
||||
new ProcessImpl(di.getPid()).destroy();
|
||||
} catch (IOException t) {
|
||||
System.out.println("Daemon " + di.getUid() + ": " + t.getMessage());
|
||||
} catch (Exception t) {
|
||||
System.out.println("Daemon " + di.getUid() + ": " + t);
|
||||
} finally {
|
||||
registry.remove(di.getUid());
|
||||
}
|
||||
}
|
||||
if (deadline < System.currentTimeMillis() && !registry.getAll().isEmpty()) {
|
||||
throw new RuntimeException("Could not stop all mvnd daemons within " + timeout + " ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
54
integration-tests/src/test/projects/single-module/pom.xml
Normal file
54
integration-tests/src/test/projects/single-module/pom.xml
Normal file
@@ -0,0 +1,54 @@
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.jboss.fuse.mvnd.test.single-module</groupId>
|
||||
<artifactId>single-module</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven-clean-plugin.version>2.5</maven-clean-plugin.version>
|
||||
<maven-compiler-plugin.version>3.1</maven-compiler-plugin.version>
|
||||
<maven-resources-plugin.version>2.6</maven-resources-plugin.version>
|
||||
<maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.6.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>${maven-clean-plugin.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${maven-compiler-plugin.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>${maven-resources-plugin.version}</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
</project>
|
@@ -0,0 +1,9 @@
|
||||
package org.jboss.fuse.mvnd.test.single.module;
|
||||
|
||||
public class Hello {
|
||||
|
||||
public String sayHello() {
|
||||
return "Hello";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
package org.jboss.fuse.mvnd.test.single.module;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class HelloTest {
|
||||
@Test
|
||||
void hello() throws IOException {
|
||||
final String actual = new Hello().sayHello();
|
||||
Files.write(Paths.get("target/hello.txt"), actual.getBytes(StandardCharsets.UTF_8));
|
||||
Assertions.assertEquals("Hello", actual);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user