Search code examples
javaspring-bootspring-testtestcontainersspring-boot-testcontainers

When i try to test with Testcontainers more than one TestClass, others always failed


The problem is: When i try to use singleton-testcontainer, all my testclasses after first failed by assertions. It means, that even if i see in log that my scenarios was comlete success, Assertions always failed.

The fact is, when i use @Testcontainers and @Container annotation - it's all good.

My first test class.

@SpringBootTest(classes = {ContractSpringBootApplication.class})
@ExtendWith({MockitoExtension.class, OutputCaptureExtension.class})
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@ActiveProfiles("test")
public class UpdateMergeTest extends AbstractTestcontainersTest {

    @SpyBean
    @Autowired
    private TechMergeUpdateRepo techMergeUpdateRepo;
    
    @BeforeEach
     void clean() {
        techMergeUpdateRepo.deleteAll();
    }

My second test class. (does the same things, but used more repositories)

@SpringBootTest(classes = {ContractSpringBootApplication.class})
@ExtendWith({MockitoExtension.class, OutputCaptureExtension.class})
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@ActiveProfiles("test")
public class UpdateEntityTest extends AbstractTestcontainersTest {

    @SpyBean
    @Autowired
    private TechMergeUpdateRepo techMergeUpdateRepo;
    
    @SpyBean
    @Autowired
    private UpdateEntityRepo updateEntityRepo;
    

    @BeforeEach
     void clean() {
        techMergeUpdateRepo.deleteAll();
        updateEntityRepo.deleteAll();
    }

My "singleton" testcontainer class.

public abstract class AbstractTestcontainersTest {
    private final static String DATABASE_NAME = "test_name";

    public static final PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("postgres:12")
            .withReuse(true)
            .withDatabaseName(DATABASE_NAME);

    static {

        postgresContainer.start();

    }
    
    @DynamicPropertySource
    public static void overrideProps(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgresContainer::getJdbcUrl);
        registry.add("spring.datasource.username", postgresContainer::getUsername);
        registry.add("spring.datasource.password", postgresContainer::getPassword);
        registry.add("spring.datasource.driver-class-name", postgresContainer::getDriverClassName);
    }


}

After tests i always get this: enter image description here

BUT!

If I change my AbstractTestcontainersTest for:

@Slf4j
@Testcontainers
public abstract class AbstractTestcontainersTest {

    private final static String DATABASE_NAME = "test_name";

    @Container
    public static final PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("postgres:12")
            .withReuse(true)
            .withDatabaseName(DATABASE_NAME);

    static {
        postgresContainer.start();
      
    }

    @DynamicPropertySource
    public static void overrideProps(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgresContainer::getJdbcUrl);
        registry.add("spring.datasource.username", postgresContainer::getUsername);
        registry.add("spring.datasource.password", postgresContainer::getPassword);
        registry.add("spring.datasource.driver-class-name", postgresContainer::getDriverClassName);

    }


}

It will start working correctly.

enter image description here

I checked the log output. The feeling is that the problem is somewhere in the “underrun” of Spring tests, in test classes, starting from the second. I checked the logs - my “scenarion” is fully completed and works correctly, but the assertions are falling

I checked the log output. The feeling is that the problem is somewhere in the “underrun” of Spring tests, in test classes, starting from the second.


Solution

  • The problem was using @SpyBean annotations.

    Because the context was not re-raised completely, in the case of a singleton test container. When asserting, all @SpyBeans after the first class pointed to Proxy without explicit proxying.

    Moving the @SpyBean annotated injections to the base class (AbstractTestcontainersTest) solved the problem.