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);
}
}
CodePudding user response:
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.