flyway-test-extensions
flyway-test-extensions copied to clipboard
@FlywayTest not working on abstract classes?
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
..
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 Alright. Thank you for the hint. I will try this once I am back on it :)
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.
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.