I have a standalone Spring Boot @Service
in its own repository. The repository is a "helper library" and does not itself contain a @SpringBootApplication
or any @RestController
. The Service uses an Autowired S3Template
from Spring Cloud AWS.
How can I write integration tests of the @Service
without using @SpringBootApplication
or having a main class?
I've seen several related answers involving @TestConfiguration
and other annotations, but am struggling to put the pieces together and get this working with Spring Boot 3.3.x.
I have produced a minimal, reproducible example (Spring Boot 3.3, JDK 21) at:
As-is, this will run cleanly with passing tests using mvn clean test
-- however, only because I have added a @SpringBootApplication
in src/test
. This does not seem like the idiomatic way, and this approach will break if I attempt to use Maven Failsafe Plugin to run integration tests "the right way".
To be clear, I do not want to do any mocking here--I want to test the real service as-is, in this case against an actual Amazon S3 (development) environment.
What I have tried:
I've tried using @TestConfiguration
, but am getting errors related to autowiring/beans:
// TestConfig.java
package foo.demo;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
@TestConfiguration
public class TestConfig {
@Bean
public DemoService service() {
return new DemoService();
}
}
// DemoApplicationTests.java
...
@ExtendWith(SpringExtension.class)
@Import(TestConfig.class)
class DemoApplicationTests {
@Autowired
private DemoService service;
...
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'service': Unsatisfied dependency expressed through field 's3Template': No qualifying bean of type 'io.awspring.cloud.s3.S3Template' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Spring Boot docs contains a guide for Creating a Multi Module Project. Section "Testing the Service Component" contains
@SpringBootTest("service.message=Hello")
public class MyServiceTest {
@Autowired
private MyService myService;
@Test
public void contextLoads() {
assertThat(myService.message()).isNotNull();
}
@SpringBootApplication // this is the one you need
static class TestConfiguration {
}
}
An alternative is to add this to a separate class TestConfiguration
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class TestConfiguration {
}
If any configuration is required, put this in an application.yml or application.properties in test/resources.