Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot remove @Component when unit testing

Bear with me as this is the first time I've used Spring Boot so this is only what I think is happening...

I have a couple of methods which are annotated with @Scheduled. They work great, and I have all of the dependencies configured and injected. These dependencies are quite heavy weight, relying on internet connections etc. I've annotated them as @Lazy, so they're only instantiated at the very last minute.

However, the classes which contain the scheduled methods need to be marked with @Component which means they're created on launch. This sets off a chain reaction which creates all of my dependencies whether I actually need them for the test I'm currently running.

When I run my unit tests on our CI server, they fail because the server isn't auth'd with the database (nor should it be).

The tests which test these @Scheduled jobs inject their own mocks, so they work fine. However, the tests which are completely unrelated are causing the problems as the classes are still created. I obviously don't want to create mocks in these tests for completely unrelated classes.

How can I prevent certain a @Component from being created when the tests are running?

Scheduled jobs class:

package example.scheduledtasks;

@Component
public class ScheduledJob {

    private Database database;

    @Autowired
    public AccountsImporter(Database database) {
        this.database = database;
    }

    @Scheduled(cron="0 0 04 * * *")
    public void run() {
        // Do something with the database
    }
}

Config class:

package example

@Configuration
public class ApplicationConfig {

    @Bean
    @Lazy
    public Database database() {
        return ...;// Some heavy operation I don't want to do while testing.
    }

}

like image 265
Josh Avatar asked Oct 27 '25 07:10

Josh


2 Answers

I know you said:

I obviously don't want to create mocks in these tests for completely unrelated classes.

Still, just so you know, you can easily override the unwanted component just for this test:

@RunWith(...)
@Context...
public class YourTest {
    public static class TestConfiguration {
        @Bean
        @Primary
        public Database unwantedComponent(){
            return Mockito.mock(Database.class);
        }
    }

    @Test
    public void yourTest(){
        ...
    }
}

Similar question/answer: Override a single @Configuration class on every spring boot @Test

like image 134
alexbt Avatar answered Oct 29 '25 22:10

alexbt


Just add the following to your test class:

@MockBean
public Database d;
like image 33
membersound Avatar answered Oct 29 '25 22:10

membersound