I want to test a @Service
class that is normally called with SpringApplication.run()
.
The service class is:
@Service
@EnableConfigurationProperties(AppProperties.class)
public class MongoService {
private static final Logger logger = LoggerFactory.getLogger(MongoService.class);
private MongoClient mongoClient;
private final AppProperties properties;
@Autowired
public MongoService(AppProperties properties) {
this.properties = properties;
}
/**
* Open connection
*/
public void openConnection() {
try {
mongoClient = new MongoClient(new MongoClientURI(properties.getMongoConnectionString()));
} catch (Exception e) {
logger.error("Cannot create connection to Search&Browse database", e);
throw new BackendException("Cannot create connection to Search&Browse database");
}
}
}
When it is called by the controller started with SpringApplication.run()
, the MongoService
is not null but, when I try from a jUnit it's not working.
So, I'm trying this:
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = AppProperties.class)
public class MongoServiceTest {
private static final Logger logger = LoggerFactory.getLogger(MongoServiceTest.class);
@Autowired
MongoService mongoService;
@Test
public void MongoServiceAutowired() {
assertNotNull(mongoService);
}
}
but I'm getting this exception:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mypackage.MongoServiceTest': Unsatisfied dependency expressed through field 'mongoService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'mypackage.services.mongo.MongoService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Any clue? Where am I failing?
To check the Service class, we need to have an instance of the Service class created and available as a @Bean so that we can @Autowire it in our test class. We can achieve this configuration using the @TestConfiguration annotation.
It is used to mark the class as a service provider. So overall @Service annotation is used with classes that provide some business functionalities. Spring context will autodetect these classes when annotation-based configuration and classpath scanning is used.
I assume that your AppProperties
and MongoService
is not in the same package
If not you can inject MongoService
in that way :
create another class named TestConfiguration
@ComponentScan(basePackageClasses = {
MongoService.class,
AppProperties.class
})
@SpringBootApplication
public class TestConfiguration {
public static void main(String[] args) {
SpringApplication.run(TestConfiguration.class, args);
}
}
And in the test just change to :
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
public class MongoServiceTest {
private static final Logger logger = LoggerFactory.getLogger(MongoServiceTest.class);
@Autowired
MongoService mongoService;
@Test
public void MongoServiceAutowired() {
assertNotNull(mongoService);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With