Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stop Spring Boot Test from hitting @PostContruct of SpringBootApplication class

I have a SpringBootApplication class that has a @PostConstruct method like that (it initializes the type of database connection):

@SpringBootApplication
public class SpringBootApp extends WebMvcConfigurerAdapter {

    public static boolean workOffline = false;
    private boolean setupSchema = false;
    private IGraphService graphService;
    private DbC conf;

    @Autowired
    public SpringBootApp(IGraphService graphService, DbC conf)
    {
        this.graphService = graphService;
        this.conf = conf;
    }

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

    @PostConstruct
    public void initializeDB() {
        if (workOffline) {
            conf.setupOfflineEnvironment();
            return;
        }
        else {
            conf.setupProdEnvironment();
        }
        if (setupSchema) {
            graphService.setupTestUsers();
        }
    }
}

I am also using Spring Boot Tests that extend this base class:

@RunWith(SpringRunner.class)
@Ignore
@SpringBootTest
public class BaseTest {

    @Before
    public void beforeTest() {

        if (SpringBootApp.workOffline) {
            conf.setupOfflineEnvironment();
        } else {
            conf.setupTestEnvironment();
        }

        graphService.setupTestUsers();}
    @After
    public void afterTest() {
        graphService.deleteAllData();
    }
}

My tests are under tests/ while my source code is under src/

Unfortunately there are cases that beforeTest() will execute before @PostConstuct and there are cases that it will execute after.. Is there a way to make my tests run with @SprinbBootTest without entering/constructiong the SpringBootApp class at all?

Thanks!

like image 387
Michail Michailidis Avatar asked Oct 14 '25 04:10

Michail Michailidis


1 Answers

As requested, here's an attempt using spring properties (without an IDE handy, so please forgive any mistakes)

You can set a property for your test using SpringBootTest#properties

@RunWith(SpringRunner.class)
@Ignore
@SpringBootTest(properties="springBootApp.workOffline=true")
public class BaseTest {
    @Before
    public void beforeTest() { /* setup */ }

    @After
    public void afterTest() { /* teardown */ }
}

Now that we know that we can set the spring property in the test, we can set up the application to use the property:

@SpringBootApplication
public class SpringBootApp extends WebMvcConfigurerAdapter {

    @Value("${springBootApp.workOffline:false}")
    private boolean workOffline = false;

    @Value("${springBootApp.setupSchema:false}")
    private boolean setupSchema = false;

    @PostConstruct
    public void initializeDB() {
        if (workOffline) {
            // ...
        } else {
            // ...
        }
        if (setupSchema) {
            // ...
        }
    }
}

As I've written this answer I've noticed a couple of things:

  • If you're only setting workOffline so you can run tests, then you probably just want to move the database setup actions out of the application and into the BaseTest class instead.
  • Same goes for setupSchema
  • If you are executing sql for your tests, don't forget about @Sql and @SqlGroup: https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#__sql

Anyway, good luck!

like image 129
ninj Avatar answered Oct 16 '25 17:10

ninj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!