flyway-test-extensions icon indicating copy to clipboard operation
flyway-test-extensions copied to clipboard

@FlywayTest not working on abstract classes?

Open ghost opened this issue 6 years ago • 4 comments

So I am having this abstract class to make life easier with unit tests:

@RunWith(SpringRunner.class)
@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
        properties = "spring.profiles.active=test")
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        FlywayTestExecutionListener.class
})
@FlywayTest
public abstract class AbstractLiveTest {

    @Value("${security.jwt.client-id}")
    protected String clientId;

    @Value("${security.jwt.client-secret}")
    protected String clientSecret;

    @Value("${security.jwt.client-secret-plain}")
    protected String clientSecretPlain;

    @Value("${server.port}")
    protected Integer serverPort;

    @Autowired
    protected TestRestTemplate template;

}

Notice the @FlywayTest annotation. This does not seem to work. I have to add @FlywayTest to all test classes separately e.g.

@FlywayTest
public class MyTests extends AbstractLiveTest {
}

otherwise it won't work. I do not know if this is expected or even intended but I thought I raise that issue here in case it isn't.


I am using org.flywaydb:flyway-core and org.flywaydb.flyway-test-extensions:flyway-spring-test in a Spring Boot (2.0.1.RELEASE) application.

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
<dependency>
    <groupId>org.flywaydb.flyway-test-extensions</groupId>
    <artifactId>flyway-spring-test</artifactId>
    <version>5.0.0</version>
    <scope>test</scope>
</dependency>
$ mvn dependency:tree
..
[INFO] +- org.flywaydb:flyway-core:jar:5.0.7:compile
[INFO] +- org.flywaydb.flyway-test-extensions:flyway-spring-test:jar:5.0.0:test
..

ghost avatar May 11 '18 18:05 ghost

Hi Stefan,

currently it was never a planned to use @FlywayTest on abstract classes as class level. The annotation processing for classes walk not the class level up. It hold it with tests simular to Petri see https://www.petrikainulainen.net/programming/unit-testing/3-reasons-why-we-should-not-use-inheritance-in-our-tests/.

But a work around could be following in your abstract class:

  @BeforeClass
  @FlywayTest
  public static void beforeClass() {}  

I have never tried it, but together with @BeforeClass The scanning should walk up to base class Object and search for the first combination of @BeforeClass and @FlywayTest .

Florian

FlorianGWE avatar May 14 '18 19:05 FlorianGWE

@FlorianGWE Alright. Thank you for the hint. I will try this once I am back on it :)

ghost avatar May 14 '18 19:05 ghost

I have the same problem. I noticed that if I use the deprecated FlywayTestExecutionListener from org.flywaydb.test.junit.FlywayTestExecutionListener, i can use FlywayTest on abstract classes.

marbon87 avatar Jun 26 '18 14:06 marbon87

On a similar note, what you probably want is a clean slate before each test, not only each test class.

@SpringBootTest(classes = {FooApplication.class})
@TestExecutionListeners(FlywayTestExecutionListener.class)
abstract class BaseSpringTest {
    @BeforeEach
    @FlywayTest
    void flywayClean() {
    }
}

in general when testing using BeforeClass and anything with any state on a per class basis is one of the huge no-gos. Under normal (any?) circumstances one does not want state to potentially leak between tests, you want all tests to start in a state that you are in complete control of. JUnit and probably other testing frameworks does not guarantee an order of execution - nor should they. Even though some order is often preserved on a specific version of the JVM is might change in any update (what has happened).

The second any test modifies state you have no reasonable way of knowing when it will be executed, except by isolating it in its own class. If a modification of any related state concerning your test does not cause your test to fail, you should think (and probably hard) about if either your state or your test is well defined.

ghost avatar Jun 27 '19 09:06 ghost