user952342
user952342

Reputation: 2742

Overriding spring @Configuration in an integration test

I have a spring boot configuration class like this:

@Configuration
public class ClockConfiguration {

    @Bean
    public Clock getSystemClock() {
        return Clock.systemUTC();
    }
}

and I have some integration tests like this:

@SpringBootTest(classes = MyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public abstract class AbstractIntegrationTest  {

}

and tests like this:

public class MiscTests extends AbstractIntegrationTest{

    @Test
    public void CreateSomethingThatOnlyWorksInThe Morning_ExpectCorrectResponse() {

    }

I want to be able to offset the clock bean to run some tests at different times on the day. How do I do this?

NOTE: I see several stack overflow answers similar to this, but I can't get them to work.

Based on other responses, it appears the solution should be something like:

@SpringBootTest(classes = MyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public abstract class AbstractIntegrationTest  {

    @Configuration
    class MyTestConfiguration {

        @Bean
        public Clock getSystemClock() {
            Clock realClock = Clock.systemDefaultZone();
            return Clock.offset(realClock, Duration.ofHours(9));
        }
    }
}

But nothing happens there. Do I need to @Import something? do I need to @Autowired something?

Thanks!

Upvotes: 3

Views: 2140

Answers (2)

Alexander Petrov
Alexander Petrov

Reputation: 9492

it is the @TestConfiguration annotation that you need https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/context/TestConfiguration.html

@RunWith(SpringRunner.class)
public class ClockServiceImplIntegrationTest {

    @TestConfiguration
    static class TestOverridingClockServiceConfiguration {

        @Bean
        public ClockService clockService() {
            return new ClockServiceImpl();
        }
    }

    @Autowired
    private ClockService clockService;

    @MockBean
    private ClockRepository clockRepository;

    // write test cases here
}

In the case you have existing configuration you c

Upvotes: 0

Maciej Kowalski
Maciej Kowalski

Reputation: 26492

As you are using Spring Boot you can take advantage of the @MockBean annotation:

@SpringBootTest(classes = MyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public abstract class AbstractIntegrationTest  {

    @MockBean
    private Clock clockMock;
}

Then you can stub public methods of that bean an each of the tests accordingly and uniquely:

@Test
public void CreateSomethingThatOnlyWorksInThe Morning_ExpectCorrectResponse() {
     when(clockMock.getTime()).thenReturn(..);
}

As per javadoc of @MockBean:

Any existing single bean of the same type defined in the context will be replaced by the mock.

Upvotes: 2

Related Questions