I am trying to use a combination of Surefire (or even Failsafe if I can configure it to work properly), to run my integration tests for a personal project. At present it will run 2/3 of my integration tests. The 3 classes are GameDbApplicationTests, UserDAOImplTest, & GameDAOImplTest. The first two will run, while the last one will not.
Logically it should be running all of the classes titled *Test, so I'm not sure what is going on here. I am capable of running each test class manually using IntelliJ, but the Maven test goal will not execute all of the test classes.
.\mvnw test output is included here
Note that the test lists GameDbApplicationTests & UserDAOImplTest, but not GameDAOImplTest for whatever reason.
Pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.StruckCroissant</groupId>
<artifactId>Game-DB</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Game-DB</name>
<description>Game Database Search Engine</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.vorburger.mariaDB4j</groupId>
<artifactId>mariaDB4j</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>23.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>8.0.5</version>
</plugin>
</plugins>
</build>
</project>
GameDAOImplTest
package com.StruckCroissant.GameDB.core.game;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import com.StruckCroissant.GameDB.TestDbConfig;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.junit.Test;
import org.junit.internal.runners.JUnit4ClassRunner;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#SpringBootTest
#RunWith(SpringJUnit4ClassRunner.class)
#TestPropertySource(locations = "classpath:test.properties")
#ContextConfiguration(classes = {TestDbConfig.class, GameDAOImpl.class})
class GameDAOImplTest {
#Qualifier("db-game")
#Autowired
private GameDAOImpl underTest;
#Qualifier("testTemplate")
#Autowired
private JdbcTemplate jdbcTemplate;
#Test
public void shouldGetAllGames() {
// given
// nothing
// when
List<Game> allGames = underTest.selectAllGames();
// then
allGames.forEach((game) -> assertThat(game).isInstanceOf(Game.class));
assertThat(allGames.size()).isGreaterThanOrEqualTo(30250);
}
#Test
public void shouldGetGameById() {
// given
int[] validGames = {1, 2, 3, 4, 5};
int[] invalidGames = {-4, -56, -3, 879627};
List<Optional<Game>> validResult = new ArrayList<>();
List<Optional<Game>> invalidResult = new ArrayList<>();
// when
for (int gameInt : validGames) {
Optional<Game> currentGameOpt = underTest.selectGameById(gameInt);
validResult.add(currentGameOpt);
}
for (int gameInt : invalidGames) {
Optional<Game> currentGameOpt = underTest.selectGameById(gameInt);
invalidResult.add(currentGameOpt);
}
// then
validResult.forEach((gameOpt) -> assertThat(gameOpt).get().isInstanceOf(Game.class));
invalidResult.forEach((gameOpt) -> assertThat(gameOpt).isEmpty());
}
}
UserDAOImplTest
package com.StruckCroissant.GameDB.core.user;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.catchThrowable;
import com.StruckCroissant.GameDB.TestDbConfig;
import com.StruckCroissant.GameDB.core.game.Game;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.jdbc.JdbcTestUtils;
#SpringBootTest
#RunWith(SpringJUnit4ClassRunner.class)
#TestPropertySource(locations = "classpath:test.properties")
#ContextConfiguration(classes = {TestDbConfig.class, UserDAOImpl.class})
class UserDAOImplTest {
#Qualifier("db-user")
#Autowired
private UserDAOImpl underTest;
#Qualifier("testTemplate")
#Autowired
private JdbcTemplate jdbcTemplate;
#AfterEach
void tearDown() {
JdbcTestUtils.deleteFromTables(jdbcTemplate, "user");
}
#NotNull
private String insertDefaultUserDb() {
User user = new User("test_username", "test_password", UserRoleEnum.USER, false, true);
underTest.insertUser(user);
return "test_username";
}
#NotNull
private String insertUserDb(String username) {
User user = new User(username, "test_password", UserRoleEnum.USER, false, true);
underTest.insertUser(user);
return username;
}
#NotNull
private Integer getUidFromUserObj(User userFromDb) {
return userFromDb.getId().orElseThrow();
}
#NotNull
private Integer getTestUidFromUsernameDb(String test_username) {
return underTest
.selectUserByUsername(test_username)
.flatMap(User::getId)
.orElseThrow(() -> new IllegalStateException("User not found in DB"));
}
#Test
#Order(1)
void shouldInsertAndSelectNewUser() {
// given
String test_username = insertDefaultUserDb();
// when
boolean userExists = underTest.selectUserByUsername(test_username).isPresent();
// then
assertThat(userExists).isTrue();
}
#Test
void shouldGetUidFromuser() {
// given
String test_username = insertDefaultUserDb();
// when
int uid = underTest.selectUserByUsername(test_username).flatMap(User::getId).orElse(0);
// then
assertThat(uid).isNotEqualTo(0);
}
#Test
void shouldUpdateUser() {
// given
// Init user
String test_username = insertDefaultUserDb();
int initUidDb = getTestUidFromUsernameDb(test_username);
// Updated user
String new_username = "new_account_420_updated";
String new_password = "password_updated";
User updatedUser = new User(new_username, new_password, UserRoleEnum.USER, false, true);
// Updated user
underTest.updateUserById(initUidDb, updatedUser);
User updatedUserDb = getTestUserFromUidDb(initUidDb);
int updatedUidDb = getUidFromUserObj(updatedUserDb);
// then
assertThat(updatedUidDb).isEqualTo(initUidDb);
assertThat(updatedUserDb.getUsername()).isEqualTo(new_username);
assertThat(updatedUserDb.getPassword()).isEqualTo(new_password);
}
private User getTestUserFromUidDb(int initUidDb) {
return underTest
.selectUserById(initUidDb)
.orElseThrow(() -> new RuntimeException("User not found in database"));
}
#Test
void shouldDeleteUser() {
// given
String test_username = insertDefaultUserDb();
User userFromDb = underTest.selectUserByUsername(test_username).get();
int uidFromDb = getUidFromUserObj(userFromDb);
// when
underTest.deleteUserById(uidFromDb);
boolean userExists = underTest.selectUserByUsername(test_username).isPresent();
// then
assertThat(userExists).isFalse();
}
#Test
void shouldGetSavedGames() {
// given
int[] games = {1, 2, 3}; // Test games
String test_username = insertDefaultUserDb();
User userFromDb = underTest.selectUserByUsername(test_username).orElseThrow();
int uid = getUidFromUserObj(userFromDb);
// when
for (int gid : games) {
underTest.insertSavedGame(uid, gid);
}
// then
assertThat(underTest.selectSavedGames(uid).size()).isNotEqualTo(0);
underTest.selectSavedGames(uid).forEach(g -> assertThat(g).isExactlyInstanceOf(Game.class));
}
#Test
void shouldDeleteSavedGame() {
// given
int[] games = {1, 2, 3}; // Test games
String test_username = insertDefaultUserDb();
User userFromDb = underTest.selectUserByUsername(test_username).orElseThrow();
int uid = getUidFromUserObj(userFromDb);
// when
for (int gid : games) {
underTest.insertSavedGame(uid, gid);
}
underTest.deleteSavedGame(uid, games[0]);
underTest.deleteSavedGame(uid, games[1]);
underTest.deleteSavedGame(uid, games[2]);
// then
assertThat(underTest.selectSavedGames(uid).size()).isEqualTo(0);
}
#Test
void shouldDetectNonUniqueUser() {
// given
String test_username = insertDefaultUserDb();
User userFromDb = underTest.selectUserByUsername(test_username).orElseThrow();
// when
boolean userIsUnique = underTest.userIsUnique(userFromDb);
// then
assertThat(userIsUnique).isFalse();
}
#Test
void shouldSelectAllUsers() {
// given
String test_username = insertUserDb("test_username1");
String test_username2 = insertUserDb("test_username2");
String test_username3 = insertUserDb("test_username3");
// when
List<User> users = underTest.selectAllUsers();
// then
assertThat(users.size()).isEqualTo(3);
users.forEach(
(User u) -> {
assertThat(u).isExactlyInstanceOf(User.class);
assertThat(u.getUsername()).isIn(test_username, test_username2, test_username3);
});
}
#Test
void shouldThrowOnNullId() {
// given
User user = new User("test_username", "test_password", UserRoleEnum.USER, false, true);
// when
Throwable thrown = catchThrowable(() -> underTest.userIsUnique(user));
// then
assertThat(thrown).isExactlyInstanceOf(IllegalArgumentException.class);
}
}
GameDbApplicationTests
package com.StruckCroissant.GameDB;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
#SpringBootTest
class GameDbApplicationTests {
#Test
void contextLoads() {}
}
TestDbConfig
package com.StruckCroissant.GameDB;
import ch.vorburger.exec.ManagedProcessException;
import ch.vorburger.mariadb4j.DB;
import ch.vorburger.mariadb4j.DBConfiguration;
import ch.vorburger.mariadb4j.DBConfigurationBuilder;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
#Configuration
#PropertySource("classpath:test.properties")
public class TestDbConfig {
#Bean
public DBConfiguration dbConfig() {
DBConfigurationBuilder config = DBConfigurationBuilder.newBuilder();
//Port not set to allow new instances to be generated for batch of tests
config.setSecurityDisabled(true);
return config.build();
}
#Bean
public DataSource dataSource(
#Autowired DBConfiguration dbConfig,
#Value("${test.datasource.name}") String databaseName,
#Value("${test.datasource.username}") String datasourceUsername,
#Value("${test.datasource.username}") String datasourcePassword,
#Value("${test.datasource.driver-class-name}") String datasourceDriver)
throws ManagedProcessException {
DB db = DB.newEmbeddedDB(dbConfig);
db.start();
db.createDB(databaseName, "root", "");
db.source("db/init/schema.sql", databaseName);
DBConfiguration dbConfiguration = db.getConfiguration();
return DataSourceBuilder.create()
.driverClassName(datasourceDriver)
.url(dbConfiguration.getURL(databaseName))
.username(datasourceUsername)
.password(datasourcePassword)
.build();
}
#Bean("testTemplate")
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
I was able to resolve the issue by myself. The problem was due to inadvertent usage of both JUnit4 and Junit5.
I was using the #AfterEach annotation in my test classes, which is defined by Junit5 and therefore imported into the test classes. I was also adding JUnit5 via the spring-boot-starter-test dependency. After removing all refrences to JUnit5 the issue is resolved.
I'm having a strange problem with maven test with Junit 5.
I'd created the test suites with junit tools for each method, every test starts like this.
private Class2Test createTestSubject() {
return new Class2Test();
}
public void test1() throws Exception {
Class2Test testSubject;
String result;
// default test
testSubject = createTestSubject();
result = testSubject.getData();
//testing, assert
}
The line
result = testSubject.getData();
returns a NullPointerException
When I execute the same test via eclipse finish ok. The surefire plugin are defined
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.0</version>
</dependency>
</dependencies>
<configuration>
<systemPropertyVariables>
<entorno>${project.basedir}\resources\maqueta.properties</entorno>
<hibernate>${project.basedir}\resources\hibernate.cfg.xml</hibernate>
</systemPropertyVariables>
<parallel>classes</parallel>
<threadCount>10</threadCount>
</configuration>
</plugin>
I'd tried to change the declaration of the object to dogde the nullpointer but it fails.
Class2Test() is the default constructor, doesn't requiere parameters or read files.
package test.com.my.myself;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import javax.annotation.Generated;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.junit.tools.configuration.base.MethodRef;
import com.my.myself.Class2Test;
import com.google.gson.Gson;
import junitparams.JUnitParamsRunner;
#Generated(value = "org.junit-tools-1.1.0")
#RunWith(JUnitParamsRunner.class)
public class Tester1{
private Class2Test createTestSubject() {
return new Class2Test();
}
#DisplayName("TEST1")
#MethodRef(name = "test1", signature = "()QString;")
#Test
public void test1() throws Exception {
Class2Test testSubject;
String result;
// default test
testSubject = createTestSubject();
result = testSubject.test1();
}
}
and the class to test
public class Class2Test{
private Connection conn = new Connector();
private static final Logger logger = Logger.getLogger(Class2Test.class);
public String test1() {
PrepareStatement pstm = conn.prepareStatement("select 1 from dual");
ResultSet rs = pstm.executeQuery();
...
return 1;
}
}
There was a problem with pom.xml the resources folder was wrong setted. :(
I am pretty new to Spring Boot, Apache Camel and the ActiveMQ broker. I am trying to create an application which will send a message to a queue which I am hosting locally using Camel for routing.
POM:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>2.22.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-activemq</artifactId>
<version>3.2.0</version>
</dependency>
MsgRouteBuilder:
public void configure() throws Exception {
from("direct:firstRoute")
.setBody(constant("Hello"))
.to("activemq:queue:myQueue");
}
application.yaml:
activemq:
broker-url: tcp://localhost:61616
user: meAd
password: meAd
MainApp.java:
package me.ad.myCamel;
import org.apache.camel.CamelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import me.ad.myCamel.router.MessageRouteBuilder;
#SpringBootApplication
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
#EnableAspectJAutoProxy(proxyTargetClass = true)
#EnableCaching
public class MeAdApp implements CommandLineRunner {
private static final Logger LOG = LoggerFactory.getLogger(MeAdApp.class);
public static void main(String[] args) {
try {
SpringApplication.run(MeAdApp.class, args);
} catch (Exception ex) {
LOG.error(ex.getMessage(), ex);
}
}
#Override
public void run(String... args) throws Exception {
LOG.info("Starting MeAdApp...");
}
}
MyController.java :
#GetMapping(value = "/routing")
public boolean sendToMyQueue() {
sendMyInfo.startRouting();
return true;
}
SendMyInfo.java :
MsgRouteBuilder routeBuilder = new MsgRouteBuilder();
CamelContext ctx = new DefaultCamelContext();
public void startRouting(){
try {
ctx.addRoutes(routeBuilder);
ctx.start();
Thread.sleep(5 * 60 * 1000);
ctx.stop();
}
catch (Exception e) {
e.printStackTrace();
}
}
So, whenever I call my rest end point: /routing, I get the error:
java.lang.NoSuchMethodError: org.apache.camel.RuntimeCamelException.wrapRuntimeException(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;`
Can anybody please point me to the right direction as to why I am getting this error? Any help is greatly appreciated .
You need to have the components of the same version. If you are using camel-core with 3.2.0, use camel-activemq 3.2.0. And, since you are using spring-boot, you can make use of the starter dependencies. Just add these and you are good to go.
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-activemq-starter</artifactId>
<version>3.2.0</version>
</dependency>
In my Java and maven project I have used cucumber for BDD test.
Here is the dependency I use:
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.2.0</version>
</dependency>
my Hooks class:
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.AfterStep;
import cucumber.api.java.BeforeStep;
public class Hooks {
#Before
public void init() {
System.out.println( " Before Scenario " );
}
#After
public void cleanUp() {
System.out.println( " After Scenario " );
}
#BeforeStep
public void beforeStep() {
System.out.println("======> This is before step <======");
//Do something before executing the step
}
#AfterStep
public void afterStep() {
System.out.println("======> This is after step <======");
}
}
But when I run my cucumber test it just prints Before Scenario, and After Scenario. Meanwhile, I expect to see, This is before step, and This is after step
before, and after each step.
So, why #AfterStep, and #BeforeStep do not work?
you should provide a small example which others can use to reproduce your problem
Have a look at this small snippet which is working
Assume the following structure
pom.xml
src/test/java/TestRunner.java
src/test/java/stepdefs/StepDefinitions.java
src/test/java/stepdefs/Hooks.java
src/test/resource/features/demo.feature
pom.xml
...
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<version.cucumber>4.2.0</version.cucumber>
</properties>
<dependencies>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${version.cucumber}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${version.cucumber}</version>
<scope>test</scope>
</dependency>
</dependencies>
...
TestRunner.java
import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;
#RunWith(Cucumber.class)
#CucumberOptions(
features = {"src/test/resource/features"},
glue = {"stepdefs"}
)
public class TestRunner {
}
StepDefinitions.java
package stepdefs;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
public class StepDefinitions {
#Given("^a successful step$")
public void aSuccessfulStep() {
System.out.println(" aSuccessfulStep()");
}
#When("doing something")
public void doingSomething() {
System.out.println(" doingSomething()");
}
#Then("something happen")
public void somethingHappen() {
System.out.println(" somethingHappen()");
}
}
Hooks.java
package stepdefs;
import cucumber.api.java.After;
import cucumber.api.java.AfterStep;
import cucumber.api.java.Before;
import cucumber.api.java.BeforeStep;
public class Hooks {
#Before
public void init() {
System.out.println("#Before scenario");
}
#After
public void cleanUp() {
System.out.println("#After scenario");
}
#BeforeStep
public void beforeStep() {
System.out.println(" #BeforeStep");
}
#AfterStep
public void afterStep() {
System.out.println(" #AfterStep");
}
}
demo.feature
Feature: Test cucumber reporting plugin
Scenario: Run a non failing scenario
Given a successful step
When doing something
Then something happen
running the tests
$ mvn clean test
produces following output
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running TestRunner
#Before scenario
#BeforeStep
aSuccessfulStep()
#AfterStep
#BeforeStep
doingSomething()
#AfterStep
#BeforeStep
somethingHappen()
#AfterStep
#After scenario
1 Scenarios (1 passed)
3 Steps (3 passed)
I see this is a tough question for Play. A lot of people asked that question, but still it is not clear how to get bytes from request body if content type is not set in Java.
There is a solution in Scala, but it is not working for my case.
I want to use Play to built a http mock server in a test in Java.
#BodyParser.Of(BodyParser.Raw.class) has no sense
package org.dan;
import org.junit.Test;
import play.mvc.BodyParser;
import play.mvc.Result;
import play.server.Server;
//import static play.mvc.Controller.request;
import static play.mvc.Results.ok;
import static play.routing.RoutingDsl.fromComponents;
import static play.server.Server.forRouter;
import static play.mvc.Http.Context.Implicit.request;
public class DemoPlayTest {
#Test
public void run() throws InterruptedException {
Server server = forRouter(
9001,
(components) ->
fromComponents(components)
.POST("/echo")
.routeTo(DemoPlayTest::action)
.build());
Thread.sleep(1111111);
}
#BodyParser.Of(BodyParser.Raw.class)
public static Result action() {
return ok("Gut: " + request().body().asRaw() + "\n");
}
}
Testing:
$ curl -v -X POST -d hello http://localhost:9001/echo
Gut: null
Dependencies:
<play.version>2.6.17</play.version>
<dependency>
<groupId>com.typesafe.play</groupId>
<artifactId>play-server_2.11</artifactId>
<version>${play.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.typesafe.play</groupId>
<artifactId>play-akka-http-server_2.11</artifactId>
<version>${play.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.typesafe.play</groupId>
<artifactId>play-java_2.11</artifactId>
<version>${play.version}</version>
<scope>test</scope>
</dependency>
package org.dan;
import org.junit.Test;
import play.mvc.Result;
import play.server.Server;
import static play.mvc.Controller.request;
import static play.mvc.Results.ok;
import static play.routing.RoutingDsl.fromComponents;
import static play.server.Server.forRouter;
public class DemoPlayTest {
#Test
public void run() throws InterruptedException {
Server server = forRouter(
9001,
(components) ->
fromComponents(components)
.POST("/echo")
.routeTo(DemoPlayTest::action)
.build());
Thread.sleep(1111111);
}
public static Result action() {
final String body = new String(request().body().asBytes().toArray());
return ok("Gut: " + body + "\n");
}
}