1

I am currently trying to test my repositories with JUnit and Assertj. This is my test folder structure:

Here is my entire application folder structure:

Also all the folders are marked correctly.

This is my application.properties in which I try to configure a in memory h2 db:

# Datasource Settings
spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# Hibernate Settings
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.show_sql=false
# H2 Console Settings
spring.h2.console.enabled=true
spring.h2.console.path=/h2

And finally this is my test class to test LehrerRepository.java

package de.gabriel.vertretungsplan.repositories;

import de.gabriel.vertretungsplan.models.enums.Anwesenheit;
import de.gabriel.vertretungsplan.models.enums.Rolle;
import de.gabriel.vertretungsplan.models.users.Lehrer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;

import java.util.List;
import java.util.Optional;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@ActiveProfiles("test")
@DataJpaTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class LehrerRepositoryTest {

    @Autowired
    private LehrerRepository lehrerRepository;

    @BeforeAll
    void init() {
        lehrerRepository.saveAllAndFlush(List.of(
                new Lehrer("chemielehrer", "chemielehrer", Rolle.getPrefixedRolle(Rolle.LEHRER), Anwesenheit.ANWESEND),
                new Lehrer("mathematiklehrer", "mathematiklehrer", Rolle.getPrefixedRolle(Rolle.LEHRER), Anwesenheit.ABWESEND)
        ));
    }
    @AfterAll
    void tearDown() {
        lehrerRepository.deleteAll();
    }

    @Test
    void findByAnwesenheit() {
        List<Lehrer> anwesend = lehrerRepository.findByAnwesenheit(Anwesenheit.ANWESEND);
        List<Lehrer> abwesend = lehrerRepository.findByAnwesenheit(Anwesenheit.ABWESEND);

        assertThat(anwesend).isNotNull();
        assertThat(abwesend).isNotNull();

        assertThat(anwesend.get(0).getUsername()).isEqualTo("chemielehrer");
        assertThat(abwesend.get(0).getUsername()).isEqualTo("mathematiklehrer");
    }

    @Test
    void findByName() {
        Optional<Lehrer> chemielehrer = lehrerRepository.findByName("chemielehrer");
        assertThat(chemielehrer).isNotEmpty();
        assertThat(chemielehrer.get().getUsername()).isEqualTo("chemielehrer");
    }
}

This is part of the error log (where the error occurs):

java.lang.IllegalStateException: Failed to load ApplicationContext for [MergedContextConfiguration@35ff8fc9 testClass = de.gabriel.vertretungsplan.repositories.LehrerRepositoryTest, locations = [], classes = [de.gabriel.vertretungsplan.VertretungsplanApplication], contextInitializerClasses = [], activeProfiles = ["test"], propertySourceLocations = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper=true"], contextCustomizers = [[ImportsContextCustomizer@5fb7183b key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@359df09a, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@792b749c, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@66982506, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@9da1, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@dddf414e, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@30f842ca, org.springframework.boot.test.context.SpringBootTestAnnotation@b55a11a], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]

    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:141)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:127)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:141)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:97)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:249)
    at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
    at java.base/java.util.Optional.orElseGet(Optional.java:364)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
    at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$before$2(ClassBasedTestDescriptor.java:203)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:202)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:84)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:148)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.IllegalStateException: Unable to retrieve @EnableAutoConfiguration base packages
    at org.springframework.boot.autoconfigure.AutoConfigurationPackages.get(AutoConfigurationPackages.java:78)
    at org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport.getBasePackages(AbstractRepositoryConfigurationSourceSupport.java:79)
    at org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport$AutoConfiguredAnnotationRepositoryConfigurationSource.getBasePackages(AbstractRepositoryConfigurationSourceSupport.java:138)
    at org.springframework.data.repository.config.RepositoryConfigurationSourceSupport.lambda$getCandidates$1(RepositoryConfigurationSourceSupport.java:75)
    at org.springframework.data.util.LazyStreamable.stream(LazyStreamable.java:47)
    at org.springframework.data.util.LazyStreamable.iterator(LazyStreamable.java:42)
    at org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport.getRepositoryConfigurations(RepositoryConfigurationExtensionSupport.java:80)
    at org.springframework.data.repository.config.RepositoryConfigurationDelegate.registerRepositoriesIn(RepositoryConfigurationDelegate.java:163)
    at org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport.registerBeanDefinitions(AbstractRepositoryConfigurationSourceSupport.java:62)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromRegistrars$1(ConfigurationClassBeanDefinitionReader.java:373)
    at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:372)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:148)
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:409)
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:283)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:344)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:745)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:565)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
    at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:59)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:47)
    at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1386)
    at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:543)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:183)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
    ... 65 more

I can see that is has problems finding some Application Context, but in the tutorial I watched there is no mention of another config class.

What I have tried

<dependency>
     <groupId>org.assertj</groupId>
     <artifactId>assertj-core</artifactId>
     <version>3.24.2</version>
     <scope>test</scope>
</dependency>
<dependency>
     <groupId>org.junit.jupiter</groupId>
     <artifactId>junit-jupiter-engine</artifactId>
     <version>5.9.2</version>
     <scope>test</scope>
</dependency>
<dependency>
     <groupId>org.mockito</groupId>
     <artifactId>mockito-core</artifactId>
     <version>5.2.0</version>
     <scope>test</scope>
</dependency>
<dependency>
     <groupId>com.h2database</groupId>
     <artifactId>h2</artifactId>
     <version>2.1.214</version>
     <scope>test</scope>
</dependency>
  • I tried the @SpringBootTest annotation but this just gives me a new error

java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [de.gabriel.vertretungsplan.repositories.LehrerRepositoryTest]: [@org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.context.SpringBootTestContextBootstrapper.class), @org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper.class)]

    at org.springframework.test.context.BootstrapUtils.resolveExplicitTestContextBootstrapper(BootstrapUtils.java:194)
    at org.springframework.test.context.BootstrapUtils.resolveTestContextBootstrapper(BootstrapUtils.java:150)
    at org.springframework.test.context.BootstrapUtils.resolveTestContextBootstrapper(BootstrapUtils.java:126)
    at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:122)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore.lambda$getOrComputeIfAbsent$4(ExtensionValuesStore.java:86)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.computeValue(ExtensionValuesStore.java:223)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$MemoizingSupplier.get(ExtensionValuesStore.java:211)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.evaluate(ExtensionValuesStore.java:191)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore$StoredValue.access$100(ExtensionValuesStore.java:171)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore.getOrComputeIfAbsent(ExtensionValuesStore.java:89)
    at org.junit.jupiter.engine.execution.ExtensionValuesStore.getOrComputeIfAbsent(ExtensionValuesStore.java:93)
    at org.junit.jupiter.engine.execution.NamespaceAwareStore.getOrComputeIfAbsent(NamespaceAwareStore.java:61)
    at org.springframework.test.context.junit.jupiter.SpringExtension.getTestContextManager(SpringExtension.java:294)
    at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:138)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$10(ClassBasedTestDescriptor.java:377)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:382)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$11(ClassBasedTestDescriptor.java:377)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestInstancePostProcessors(ClassBasedTestDescriptor.java:376)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$instantiateAndPostProcessTestInstance$6(ClassBasedTestDescriptor.java:289)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:288)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
    at java.base/java.util.Optional.orElseGet(Optional.java:364)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
    at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$before$2(ClassBasedTestDescriptor.java:203)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:202)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:84)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:148)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
  • Renaming application.properties to application-test.properties and configuring test as the active profile:
spring.config.activate.on-profile=test
  • I also tried some annotations suggested to me in the comments:
@EntityScan(basePackages = "de.gabriel.vertretungsplan.models")
@EnableJpaRepositories(basePackages = "de.gabriel.vertretungsplan.repositories")

Using the first annotation, @EntityScan, I get: java.lang.IllegalStateException: Failed to load ApplicationContext for And using the second annotation @EnableJpaRepositories, I get: org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement

  • Making a class with the @SpringBootTest annotation to see if the application context gets loaded there. This text (contextLoads) runs successfully:
package de.gabriel.vertretungsplan;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ActiveProfiles;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@SpringBootTest
@ActiveProfiles("test")
class VertretungsplanApplicationTests {

    @Test
    void contextLoads(ApplicationContext context) {
        assertThat(context).isNotNull(); // https://www.jvt.me/posts/2021/06/25/spring-context-test/
    }
}

Debugging information on hibernate before the error occurs

Hibernate: 
    drop table if exists fach cascade 
Hibernate: 
    drop table if exists klassen cascade 
...
    drop table if exists user cascade 
2023-06-25T18:39:52.366+02:00  WARN 14848 --- [           main] o.h.t.s.i.ExceptionHandlerLoggedImpl     : GenerationTarget encountered exception accepting command : Error executing DDL "
    drop table if exists user cascade " via JDBC Statement

It seems like the error happens on dropping the "user" table? (But it doesn't seem like it is because of a reserved keyword).

As you can see I am new to unit testing and I thought it would be as simple as just annotating test methods with @Test and using the test application.properties to tell spring/junit with which db (in this case in mem h2) to use for testing, but it's just not working. Could someone please help me with what I am doing wrong?

For any one trying to help me and replicate the problem: Thank you very much, here is the whole code: https://github.com/github-gabriel/vertretungsplan-testing -> Btw, I am only using the @ActiveProfiles and @Profile annotations because I have some beans that are meant for the main application but not for testing so I exluce them like that

Gabriel
  • 233
  • 1
  • 3
  • 11
  • 1
    It's been a while since I last used `@DataJpaTest` but my suspicion is that you need to add `@EnableJpaRepositories` to your test. If in addition you run into 'not a managed type' errors, `@EntityScan` pointing to your entity packages might also be required. Please let me know if that helps – crizzis Jun 20 '23 at 22:10
  • 1
    Using only the ```@EnableJpaRepositories``` it still fails to load the application context: ```java.lang.IllegalStateException: Failed to load ApplicationContext for```. And adding the ```@EntityScan(basePackages = "de.gabriel.vertretungsplan.models")``` I get: ```org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement```. I don't get it, how can specifiying the entity location help load the app context. And how do I get SQL error if I don't write my own but use H2 Dialect, Driver etc. in application-test.properties? – Gabriel Jun 21 '23 at 12:33
  • 1
    Ok, that error you got from `@EntityScan` sounds like it's finally coming from repository initialization, which is very good. The problem I think was that `@DataJpaTest` by default only looks for entities in the package the test resides in – crizzis Jun 21 '23 at 19:14
  • We can now try to address the `InvalidDataResourceUsageException` if you post the entire stack trace – crizzis Jun 21 '23 at 19:15
  • @crizzis thank you very much for your response. I guess it is "good", I still don't get how the Spring Boot SQL Queries couldn't work with the db but has to be a setting or config or something I missed idk. Here is the link to the stack trace (gist): https://gist.github.com/github-gabriel/b252563474e8c6c5577c020c718ce677 – Gabriel Jun 21 '23 at 19:34
  • Huh, weird. Now it seems as though the test was trying to do all the right things, in the right sequence, but the JDBC dialect seems misconfigured somehow. Could you try to remove all the DB-related properties from `application.properties` for a sec and see what happens? Especially the dialect, platform, driver etc. as this is usually auto detected by Hibernate – crizzis Jun 21 '23 at 19:43
  • @crizzis I basically get the same error but it says that it couldn't find the table (Lehrer) because the db is empty: ```Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Tabelle "LEHRER" nicht gefunden (diese Datenbank ist leer)``` (sorry for the german exception but it just says "table "LEHRER" not found (this db is empty) – Gabriel Jun 21 '23 at 19:46
  • Hmm... and if you restore just the `spring.jpa.hibernate.ddl-auto=create-drop` property? Sorry for the trial and error, but I think we are getting closer to the root cause, and it might simply be that the DB was overconfigured, so to speak – crizzis Jun 22 '23 at 10:19
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/254190/discussion-between-gabriel-and-crizzis). – Gabriel Jun 22 '23 at 12:16

3 Answers3

1

There are two problems that are causing your tests to fail. The first problem is that the application context cannot be created due to Spring Boot being "unable to retrieve @EnableAutoConfiguration base packages". It's unable to retrieve the packages because you have disabled auto-configuration when the test profile is active:

@Profile("!test")
@SpringBootApplication
public class VertretungsplanApplication {

It's @SpringBootApplication that enables auto-configuration, but you have indicated that this class should be ignored when the test profile is active.

I presume that the intent was to disable the CommandLineRunner when running tests. You can do so by moving @Profile to the @Bean method:

@SpringBootApplication
public class VertretungsplanApplication {

    // …

    @Bean
    @Profile("!test")
    CommandLineRunner commandLineRunner(FachRepository fachRepository, KlasseRepository klasseRepository,

With this change in place the application context will fail to start as Hibernate tries to create a table named user and user is a reserved keyword when using H2. One way to fix this is to change the table's name:

@Entity
@Table(name="usr")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class User {

With these two changes in place LehrerRepositoryTest will pass.

Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • Thank you very much, that solved it. It makes so much sense to only set the !test profile for the commandLineRunner bean so Spring can still create the Application Context. Also thanks for pointing out the problem with the table name, I also considered that but didn't think that it could cause the SQLGrammarException because I thought a NON_KEYWORD=user in the application.properties would fix it but it doesn't because of some SQL identifier stuff. Thanks for pointing these kinda obvious (but not really obvious) things out. So opening the issue on github maybe helped :) jk – Gabriel Jun 30 '23 at 11:47
0

Possibility 1 : Your test class cannot find spring boot main class

Example : Package for the main classes is different form the test classes\

com.mainpackage.* vs com.testpackage.* P

If thats the case, try removing the

@DataJpaTest

and replacing it with

@SpringBootTest(classes = {com.mainpackage.YourSpringBootMainApplication.class})

Possibility 2 : Older Spring Boot Version 2.1 or below

If thats the case, you need to add the following annotation

@ExtendWith

As of Spring Boot 2.1, we no longer need to load the SpringExtension because it's included as a meta annotation in the Spring Boot test annotations like @DataJpaTest, @WebMvcTest, and @SpringBootTest.

Let me know if it fixes the issue or there is any change!

Edit: A sample configuration structure that works:

DTO

package com.pmanaktala.scratchpadspring;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "my_dto")
public class MyDTO {

    @Id
    private String id;

    private String name;

    //getter, setter, constructors

Repository

package com.pmanaktala.scratchpadspring;

import org.springframework.data.jpa.repository.JpaRepository;

public interface MyDTORepository extends JpaRepository<MyDTO, String> {
}   

Spring Boot Main

package com.pmanaktala.scratchpadspring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaRepositories
public class ScratchPadSpringApplication {

    public static void main(String[] args) {
        SpringApplication.run(ScratchPadSpringApplication.class, args);
    }

}

Test Class

package com.pmanaktala.scratchpadspring;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertTrue;

@DataJpaTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class LehrerRepositoryTest {

    @Autowired
    private MyDTORepository myDTORepository;

    @BeforeAll
    void init() {
        myDTORepository.saveAllAndFlush(List.of(new MyDTO("123", "Test User")));
    }

    @AfterAll
    void tearDown() {
        myDTORepository.deleteAll();
    }

    @Test
    void findById() {
        Optional<MyDTO> myDTO = myDTORepository.findById("123");

        assertTrue(myDTO.isPresent());
    }

}
Parth Manaktala
  • 1,112
  • 9
  • 27
  • 1
    Thanks for your response, my Spring Boot Version is up to date (Version 3) as well as Spring Security (which is on version 6). Testing out your first possibility I still get: ```java.lang.IllegalStateException: Failed to load ApplicationContext for``` which is caused by some bean ```Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaSharedEM_entityManagerFactory'```. I bet it is something very dumb and basic I forgot to configure or I didn't do correctly but I just can't find it, still thanks for your response – Gabriel Jun 23 '23 at 21:44
  • 1
    Is the package name same for the main and test? – Parth Manaktala Jun 23 '23 at 22:04
  • 1
    Also @Gabriel by any case are you using custom entity manager? May be this can help? https://stackoverflow.com/q/44809204/8107504 Also you need to refer to the package of that config class if it is in a different class. – Parth Manaktala Jun 23 '23 at 22:14
  • 1
    No I don't use an custom entity manager. My main application is under src/main and test is under src/test but it might actually be because of me using the wrong package. I am going to update my post/question now with the new hierachry – Gabriel Jun 23 '23 at 22:22
  • 1
    @Gabriel I updated the answer to have a sample code that works, may be cross reference the configuration, since you already have made sure the package is same now, this code might help you, also check if there is any other annotations/configuration code that could be causing the issue. If possible mention them and i can try including them and seeing if i can replicate the issue. – Parth Manaktala Jun 23 '23 at 22:40
  • Thanks for your code but mine is looking pretty similar (so still not working :/ ) and this Test Code is litteraly the only test code I have next to my app context loaded test which I probably should have included in my post. But I am going to update my post now – Gabriel Jun 23 '23 at 22:49
  • @Gabriel that is so strange, unfortunaltey like you said its a really small mistake somewhere and to debug that i feel one needs the whole code. – Parth Manaktala Jun 26 '23 at 19:49
  • Would you maybe be down to debug the project with me on discord? Sorry to ask you, but I don't know what to do. Never had a problem up for 10 days, 200+ views, 2 good answers and still not workng – Gabriel Jun 29 '23 at 17:16
0

Without actually testing it out, I think the answer lies in your stacktrace:

Caused by: java.lang.IllegalStateException: Unable to retrieve @EnableAutoConfiguration base packages
    at org.springframework.boot.autoconfigure.AutoConfigurationPackages.get(AutoConfigurationPackages.java:78)

This indicates that the a NoSuchBeanDefinitionException occured either for the beanFactory.getBean(BEAN, BasePackages.class) call or the get() call.

To further debug and understand what is going on increase logging on org.springframework.boot.autoconfigure to DEBUG, secondly I would try to debug the test execution with a breakpoint at AutoConfigurationPackages.java:78

Hope this helps you finding the issue!

  • Thanks for your answer, I didn't really get any new insight from looking at the debugger (I still don't know why the bean is missing). Debugger: https://postimg.cc/SX8wcnDD, Logs with ```logging.level.org.springframework.boot.autoconfigure=DEBUG```: https://gist.github.com/github-gabriel/94a20d15ac4f6e5e4089d098132f1e67 – Gabriel Jun 29 '23 at 12:15