1

I need to do integration testing on an ecosystem of spring boot based services. Most of these communicate with each other via REST APIs and use their own databases. Besides, there is some additional stuff that needs to be done in the test cases: Setting up clients, posting and getting data through the services' APIs, etc.

Of course, I could straightforwardly boot all services as separate applications via Java's ProcessBuilder and pass test-specific configuration as arguments (as single properties or in terms of a test-specific .yml/.properties file). But I was wondering if it is not also possible to just launch all services inside the same process, e.g, via SpringApplicationBuilder.

My central question: Is there any simple way to separate services' contexts from each other? I am not familiar with boostrap contexts yet but to me it seems that these are not applicable to Spring Boot but Spring Cloud only?

We use maven, thus the integration test project's pom.xml has depedencies to all services' projects (where the respective Application classes are located in).

My sample test code looks like this:

@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {

    @Test
    public void Test1() {
        SpringApplicationBuilder service1 = new SpringApplicationBuilder( my.service1.Application.class )
            .properties( "spring.config.location=classpath:/service1.yml" );
        service1.run();

        SpringApplicationBuilder service2 = new SpringApplicationBuilder( my.service2.Application.class )
            .properties( "spring.config.location=classpath:/service2.yml" );
        service2.run();

        // do test stuff...
    }
}

where each of the Application classes looks like

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SpringBootApplication
@EnableConfigurationProperties
public class Application {
    public static void main( String [] args ) {
        TimeZone.setDefault( TimeZone.getTimeZone( "UTC" ) );
        SpringApplication.run( Application.class, args );
    }
}

Problem is now that the two services share the same Spring context. Omitting the @RunWith(SpringJUnit4ClassRunner.class) annotation does not change this.

Thanks in advance!

Florian
  • 11
  • 2
  • It's not clear what you're asking. It sounds like the apps are running in separate JVMs and using separate DB, in which case, they don't share anything. Your test is creating different Spring applications using `SpringApplicationBuilder`, so, how exactly "_two services share the same Spring context_"? – Abhijit Sarkar Mar 15 '23 at 16:20
  • Sorry if that was confusing. They only run in separate JVMs in the production environment but for the test I try to run them in one to avoid creating so many OS processes all the time. My sample code would run them in one JVM but joins contexts. – Florian Mar 15 '23 at 18:18
  • If you want to run them as one context, what are you trying to separate? – Abhijit Sarkar Mar 15 '23 at 19:40
  • I do not want to run them as one context. Same JVM does not necessarily mean same Spring Context, does it? There are multiple reasons why I would prefer running all services inside one JVM for integration testing, e. g. It makes comparing data in junit assert statements easier. However when service1 and service2 are launched as above, they conflict when creating their respective beans. – Florian Mar 15 '23 at 21:20

0 Answers0