-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Abstract classes with @Nested
are not ignored / not handled properly
#2717
Comments
What is the use case for having an
|
Or are you claiming there is no use case and that you would prefer a better (more informative) error message? |
Yes that was what I meant. Either a better error message or such classes being ignored (similar to other cases mentioned in #242). Personally I would prefer an error to make the user aware of the issue, since it is not known yet when 242 will be resolved. |
Team decision: Let's introduce a proper error message for this scenario when tackling #242. |
Hi @marcphilipp I know that this is closed under the pretense that there is no valid use case for the @nested abstract classes, but I would like to argue otherwise, as I am facing this very limitation within the framework right now. I am a developing an application where my domain logic is decoupled from outside things ( usually databases but also some other things ) via interfaces. This is where a use case for package udarnicka.recipes.crud.persistence;
import jdk.jfr.Description;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.data.repository.CrudRepository;
import udarnicka.common.CanonicalName;
import udarnicka.common.HasCanonicalName;
import udarnicka.common.HasId;
import udarnicka.common.SerialInteger;
import udarnicka.recipes.crud.domain.ports.*;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.*;
import static org.assertj.core.api.Assertions.*;
public abstract class RecipeRepositoryAbstractTest {
@Nested
@Description("If there is a database")
public class GivenADatabase {
@Nested
@Description("which contains no recipes")
public class WhichIsEmpty<Entity extends HasId<?> & HasCanonicalName, DataSource extends CrudRepository<Entity, ?>> {
protected RecipeRepository recipeRepository;
protected DataSource dataSource;
@Test
@Description("then new Recipes can be saved into the database")
protected void thenNewRecipesCanBeSavedIntoTheDatabase() {...}
@Test
@Description("then recipe with same canonical name can not be saved into database twice")
protected void recipeWithSameNameCanNotBeCreatedTwice() {...}
@Test
@Description("then deleting any recipe returns an empty Optional")
protected void deletingAnyRecipeReturnsEmtpyOptional() {...}
@Test
@Description("then reading any ingredient returns an empty Optional")
protected void readingANonexistentRecipeReturnsAnEmptyOptional() {...}
}
@Nested
@Description("which contains some recipes")
public class WhichContainsSomeRecipes<Entity extends HasId<?> & HasCanonicalName, DataSource extends CrudRepository<Entity, ?>> {
@PersistenceContext
private EntityManager em;
private List<Recipe> recipesInDb;
protected DataSource dataSource;
protected RecipeRepository recipeRepository;
protected void initializeData() {...}
@Test
@Description("then deleting a recipe removes it from the database")
protected void deletingTheRecipeRemovesItFromTheDatabase() {...}
@Test
@Description("then deleting a recipe returns the recipe")
protected void deletingTheRecipeReturnsDeletedRecipe() {...}
@Test
@Description("then the existing recipe can be read")
protected void existingRecipeCanBeRead() {...}
}
}
} I would then like to implement this for concrete implementation of package udarnicka.recipes.crud.persistence.jpa;
import jdk.jfr.Description;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import udarnicka.recipes.crud.persistence.RecipeRepositoryAbstractTest;
public class JpaRecipeRepositoryTest extends RecipeRepositoryAbstractTest {
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
public class GivenAPostgresDatabase extends GivenADatabase {
@Container
private static final PostgreSQLContainer<?> container = new PostgreSQLContainer<>("postgers:14");
@DynamicPropertySource
static void registerProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", container::getJdbcUrl);
registry.add("spring.datasource.username", container::getUsername);
registry.add("spring.datasource.password", container::getPassword);
}
@Nested
public class WhichIsEmptyPostgresDatabase extends WhichIsEmpty<RecipeJpaEntity, SpringDataRecipeRepository> {
@Autowired
private SpringDataRecipeRepository springDataRecipeRepository;
@BeforeEach
@Override
protected void setup() {
this.recipeRepository = new JpaRecipeRepository(springDataRecipeRepository);
this.dataSource = springDataRecipeRepository;
}
}
@Nested
public class WhichContainsSomeRecipesPostgres extends WhichContainsSomeRecipes<RecipeJpaEntity, SpringDataRecipeRepository> {
@Autowired
private SpringDataRecipeRepository springDataRecipeRepository;
@BeforeEach()
void setup() {
this.recipeRepository = new JpaRecipeRepository(springDataRecipeRepository);
this.dataSource = springDataRecipeRepository;
}
}
}
} This does not work though due to errors pointed out in this issue. I would really see this as a valid use case to nicely organize the test cases which rely on presence of a database, and handle the database in different states. I am also not quite sure, what the elegant alternative to this issue would be. |
Description
The predicate for whether a class annotated with
@Nested
can be executed does not check whether the class is abstract, seeIsNestedTestClass
. This causes ajava.lang.InstantiationException
when trying to run the tests (from within Eclipse IDE).The predicate for top level test classes in
IsPotentialTestContainer
excludes abstract classes.In case you decide to indeed ignore abstract nested classes, then error handling for that would probably have to be part of #242.
Steps to reproduce
Try to run the following test:
Context
The text was updated successfully, but these errors were encountered: