Adds an example for an E2E system test that leverages Kafka for JUnit
This commit is contained in:
@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,9 +38,11 @@ public class ItemsCommandResource {
|
|||||||
|
|
||||||
log.info("Received a create item request with data {}.", createItem);
|
log.info("Received a create item request with data {}.", createItem);
|
||||||
|
|
||||||
|
ItemCommand createItemCommand = commandsFor(createItem);
|
||||||
|
|
||||||
return commandHandler
|
return commandHandler
|
||||||
.onCommand(commandsFor(createItem))
|
.onCommand(createItemCommand)
|
||||||
.thenApply(dontCare -> ResponseEntity.accepted().build())
|
.thenApply(dontCare -> ResponseEntity.created(itemUri(createItemCommand.getItemId())).build())
|
||||||
.exceptionally(e -> {
|
.exceptionally(e -> {
|
||||||
log.warn("Caught an exception at the service boundary.", e);
|
log.warn("Caught an exception at the service boundary.", e);
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
@@ -49,4 +52,8 @@ public class ItemsCommandResource {
|
|||||||
private ItemCommand commandsFor(final CreateItemRequest createItem) {
|
private ItemCommand commandsFor(final CreateItemRequest createItem) {
|
||||||
return new CreateItem(createItem.getDescription());
|
return new CreateItem(createItem.getDescription());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private URI itemUri(final String itemId) {
|
||||||
|
return URI.create("/items/" + itemId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
88
gtd-e2e-tests/pom.xml
Normal file
88
gtd-e2e-tests/pom.xml
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>net.mguenther.gtd</groupId>
|
||||||
|
<artifactId>gtd-parent</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>gtd-e2e-tests</artifactId>
|
||||||
|
<version>0.1.0-SNAPSHOT</version>
|
||||||
|
<name>gtd-e2e-tests</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- Intra-project dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.mguenther.gtd</groupId>
|
||||||
|
<artifactId>gtd-common</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.mguenther.gtd</groupId>
|
||||||
|
<artifactId>gtd-codec</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- HTTP client -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-httpclient</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-slf4j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-jackson</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-jaxrs</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>${httpclient.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<!-- Testing -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.mguenther.kafka</groupId>
|
||||||
|
<artifactId>kafka-junit</artifactId>
|
||||||
|
<version>${kafka.junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>${junit.jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit.jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hamcrest</groupId>
|
||||||
|
<artifactId>hamcrest-core</artifactId>
|
||||||
|
<version>${hamcrest.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package net.mguenther.gtd.client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Markus Günther (markus.guenther@gmail.com)
|
||||||
|
*/
|
||||||
|
public class CreateItem {
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
public CreateItem(final String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "CreateItemRequest{" +
|
||||||
|
"description='" + description + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package net.mguenther.gtd.client;
|
||||||
|
|
||||||
|
import feign.Headers;
|
||||||
|
import feign.Param;
|
||||||
|
import feign.RequestLine;
|
||||||
|
import feign.Response;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface GettingThingsDone {
|
||||||
|
|
||||||
|
@RequestLine("POST /items")
|
||||||
|
@Headers("Content-Type: application/json")
|
||||||
|
Response createItem(CreateItem payload);
|
||||||
|
|
||||||
|
@RequestLine("PUT /items/{itemId}")
|
||||||
|
@Headers("Content-Type: application/json")
|
||||||
|
Response updateItem(@Param("itemId") String itemId, UpdateItem payload);
|
||||||
|
|
||||||
|
@RequestLine("GET /items/{itemId}")
|
||||||
|
@Headers("Accept: application/json")
|
||||||
|
Item getItem(@Param("itemId") String itemId);
|
||||||
|
|
||||||
|
@RequestLine("GET /items")
|
||||||
|
@Headers("Accept: application/json")
|
||||||
|
List<Item> getItems();
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package net.mguenther.gtd.client;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Markus Günther (markus.guenther@gmail.com)
|
||||||
|
*/
|
||||||
|
public class Item {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private int requiredTime;
|
||||||
|
|
||||||
|
private Date dueDate;
|
||||||
|
|
||||||
|
private List<String> tags;
|
||||||
|
|
||||||
|
private String associatedList;
|
||||||
|
|
||||||
|
private boolean done;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDone() {
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRequiredTime() {
|
||||||
|
return requiredTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDueDate() {
|
||||||
|
return dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTags() {
|
||||||
|
return Collections.unmodifiableList(tags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAssociatedList() {
|
||||||
|
return associatedList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package net.mguenther.gtd.client;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Markus Günther (markus.guenther@gmail.com)
|
||||||
|
*/
|
||||||
|
public class UpdateItem {
|
||||||
|
|
||||||
|
private Long dueDate;
|
||||||
|
|
||||||
|
private Integer requiredTime;
|
||||||
|
|
||||||
|
private List<String> tags;
|
||||||
|
|
||||||
|
private String associatedList;
|
||||||
|
|
||||||
|
public Long getDueDate() {
|
||||||
|
return dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDueDate(long dueDate) {
|
||||||
|
this.dueDate = dueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getRequiredTime() {
|
||||||
|
return requiredTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequiredTime(int requiredTime) {
|
||||||
|
this.requiredTime = requiredTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTags() {
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTags(List<String> tags) {
|
||||||
|
this.tags = tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAssociatedList() {
|
||||||
|
return associatedList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAssociatedList(String associatedList) {
|
||||||
|
this.associatedList = associatedList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "UpdateItemRequest{" +
|
||||||
|
"dueDate=" + dueDate +
|
||||||
|
", requiredTime=" + requiredTime +
|
||||||
|
", tags=" + tags +
|
||||||
|
", associatedList='" + associatedList + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
package net.mguenther.gtd;
|
||||||
|
|
||||||
|
import feign.Feign;
|
||||||
|
import feign.Logger;
|
||||||
|
import feign.Response;
|
||||||
|
import feign.httpclient.ApacheHttpClient;
|
||||||
|
import feign.jackson.JacksonDecoder;
|
||||||
|
import feign.jackson.JacksonEncoder;
|
||||||
|
import feign.slf4j.Slf4jLogger;
|
||||||
|
import net.mguenther.gtd.client.CreateItem;
|
||||||
|
import net.mguenther.gtd.client.GettingThingsDone;
|
||||||
|
import net.mguenther.gtd.domain.event.ItemCreated;
|
||||||
|
import net.mguenther.gtd.kafka.serialization.AvroItemEvent;
|
||||||
|
import net.mguenther.gtd.kafka.serialization.ItemEventConverter;
|
||||||
|
import net.mguenther.gtd.kafka.serialization.ItemEventDeserializer;
|
||||||
|
import net.mguenther.kafka.junit.ExternalKafkaCluster;
|
||||||
|
import org.apache.kafka.clients.consumer.ConsumerConfig;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static net.mguenther.kafka.junit.ObserveKeyValues.on;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
public class EventPublicationTest {
|
||||||
|
|
||||||
|
private static final String URL = "http://localhost:8765/api";
|
||||||
|
|
||||||
|
private final ItemEventConverter converter = new ItemEventConverter();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void anItemCreatedEventShouldBePublishedAfterCreatingNewItem() throws Exception {
|
||||||
|
|
||||||
|
ExternalKafkaCluster kafka = ExternalKafkaCluster.at("http://localhost:9092");
|
||||||
|
GettingThingsDone gtd = createGetthingThingsDoneClient();
|
||||||
|
String itemId = extractItemId(gtd.createItem(new CreateItem("I gotta do my homework!")));
|
||||||
|
|
||||||
|
List<AvroItemEvent> publishedEvents = kafka
|
||||||
|
.observeValues(on("topic-getting-things-done", 1, AvroItemEvent.class)
|
||||||
|
.observeFor(10, TimeUnit.SECONDS)
|
||||||
|
.with(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ItemEventDeserializer.class)
|
||||||
|
.filterOnKeys(aggregateId -> aggregateId.equals(itemId)));
|
||||||
|
|
||||||
|
ItemCreated itemCreatedEvent = publishedEvents.stream()
|
||||||
|
.findFirst()
|
||||||
|
.map(converter::to)
|
||||||
|
.map(e -> (ItemCreated) e)
|
||||||
|
.orElseThrow(AssertionError::new);
|
||||||
|
|
||||||
|
assertThat(itemCreatedEvent.getItemId(), equalTo(itemId));
|
||||||
|
assertThat(itemCreatedEvent.getDescription(), equalTo("I gotta do my homework!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private GettingThingsDone createGetthingThingsDoneClient() {
|
||||||
|
return Feign.builder()
|
||||||
|
.client(new ApacheHttpClient())
|
||||||
|
.encoder(new JacksonEncoder())
|
||||||
|
.decoder(new JacksonDecoder())
|
||||||
|
.logger(new Slf4jLogger(GettingThingsDone.class))
|
||||||
|
.logLevel(Logger.Level.FULL)
|
||||||
|
.target(GettingThingsDone.class, URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractItemId(final Response response) {
|
||||||
|
return response.headers()
|
||||||
|
.get("Location")
|
||||||
|
.stream()
|
||||||
|
.findFirst()
|
||||||
|
.map(s -> s.replace("/items/", ""))
|
||||||
|
.orElseThrow(AssertionError::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,7 +30,7 @@ public class ItemQueryResource {
|
|||||||
this.itemView = itemView;
|
this.itemView = itemView;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@RequestMapping(path = "/items/{itemId}", method = RequestMethod.GET, produces = "application/json")
|
@RequestMapping(path = "/items/{itemId}", method = RequestMethod.GET, produces = "application/json")
|
||||||
public CompletableFuture<ResponseEntity<Item>> showItem(@PathVariable("itemId") String itemId) {
|
public CompletableFuture<ResponseEntity<Item>> showItem(@PathVariable("itemId") String itemId) {
|
||||||
|
|
||||||
log.info("Received a show item request for item with ID {}.", itemId);
|
log.info("Received a show item request for item with ID {}.", itemId);
|
||||||
@@ -38,5 +38,5 @@ public class ItemQueryResource {
|
|||||||
return itemView.getItem(itemId)
|
return itemView.getItem(itemId)
|
||||||
.thenApply(optionalItem -> optionalItem.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()))
|
.thenApply(optionalItem -> optionalItem.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()))
|
||||||
.exceptionally(e -> ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
|
.exceptionally(e -> ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,13 +42,5 @@ public class ItemsQueryResource {
|
|||||||
.exceptionally(e -> ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
|
.exceptionally(e -> ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(path = "/items/{itemId}", method = RequestMethod.GET, produces = "application/json")
|
|
||||||
public CompletableFuture<ResponseEntity<Item>> showItem(@PathVariable("itemId") String itemId) {
|
|
||||||
|
|
||||||
log.info("Received a show item request for item with ID {}.", itemId);
|
|
||||||
|
|
||||||
return itemView.getItem(itemId)
|
|
||||||
.thenApply(optionalItem -> optionalItem.map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build()))
|
|
||||||
.exceptionally(e -> ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
59
pom.xml
59
pom.xml
@@ -21,6 +21,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<!-- Managed dependency versions -->
|
<!-- Managed dependency versions -->
|
||||||
|
<kafka.junit.version>2.7.0</kafka.junit.version>
|
||||||
<junit.jupiter.version>5.7.0</junit.jupiter.version>
|
<junit.jupiter.version>5.7.0</junit.jupiter.version>
|
||||||
<junit.vintage.version>5.7.0</junit.vintage.version>
|
<junit.vintage.version>5.7.0</junit.vintage.version>
|
||||||
<junit.version>4.13.1</junit.version>
|
<junit.version>4.13.1</junit.version>
|
||||||
@@ -31,6 +32,8 @@
|
|||||||
<spring-cloud.version>2020.0.0</spring-cloud.version>
|
<spring-cloud.version>2020.0.0</spring-cloud.version>
|
||||||
<avro.version>1.8.1</avro.version>
|
<avro.version>1.8.1</avro.version>
|
||||||
<commons-lang3.version>3.5</commons-lang3.version>
|
<commons-lang3.version>3.5</commons-lang3.version>
|
||||||
|
<openfeign.version>11.0</openfeign.version>
|
||||||
|
<httpclient.version>4.5.13</httpclient.version>
|
||||||
<!-- Plugin versions -->
|
<!-- Plugin versions -->
|
||||||
<plugin.avro.version>1.10.1</plugin.avro.version>
|
<plugin.avro.version>1.10.1</plugin.avro.version>
|
||||||
<plugin.compiler.version>3.5</plugin.compiler.version>
|
<plugin.compiler.version>3.5</plugin.compiler.version>
|
||||||
@@ -44,6 +47,7 @@
|
|||||||
<module>gtd-query-side</module>
|
<module>gtd-query-side</module>
|
||||||
<module>gtd-api-gateway</module>
|
<module>gtd-api-gateway</module>
|
||||||
<module>gtd-discovery-service</module>
|
<module>gtd-discovery-service</module>
|
||||||
|
<module>gtd-e2e-tests</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -152,11 +156,60 @@
|
|||||||
<artifactId>log4j-over-slf4j</artifactId>
|
<artifactId>log4j-over-slf4j</artifactId>
|
||||||
<version>${slf4j.version}</version>
|
<version>${slf4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- HTTP client -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-core</artifactId>
|
||||||
|
<version>${openfeign.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-httpclient</artifactId>
|
||||||
|
<version>${openfeign.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-slf4j</artifactId>
|
||||||
|
<version>${openfeign.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-jackson</artifactId>
|
||||||
|
<version>${openfeign.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.github.openfeign</groupId>
|
||||||
|
<artifactId>feign-jaxrs</artifactId>
|
||||||
|
<version>${openfeign.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>${httpclient.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
<!-- Testing -->
|
<!-- Testing -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>net.mguenther.kafka</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>kafka-junit</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>${kafka.junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>${junit.jupiter.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit.jupiter.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
Reference in New Issue
Block a user