Reputation: 18572
I am using a mock repository for my application.
Here is snippet how service looks:
@Service
public class WeatherStationService {
@Autowired
private WeatherStationRepositoryMock weatherRepository;
Here is repository code:
@Repository
public class WeatherStationRepositoryMock {
@Getter
private List<WeatherStation> stations = new ArrayList<>(
Arrays.asList(
new WeatherStation("huston", "Huston station", RandomGenerator.getRandomGeoInformation()),
new WeatherStation("colorado", "Colorado station", RandomGenerator.getRandomGeoInformation())
)
);
It works fine when I am executing main() with @SpringBootApplication
.
However, when I want to run test class:
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MockConfig.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class WeatherStationServiceTest {
@Autowired
@Real
private WeatherStationService weatherService;
It fails with the following stacktrace:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'edu.lelyak.repository.WeatherStationRepositoryMock' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Here is MockConfig content:
@Configuration
public class MockConfig {
//**************************** REAL BEANS ******************************
@Bean
@Real
public WeatherStationService weatherServiceReal() {
return new WeatherStationService();
}
Real
is marker annotation for real instances:
@Retention(RUNTIME)
@Qualifier
public @interface Real {
}
I can fix it with next initialization at service:
@Service
public class WeatherStationService {
private WeatherStationRepositoryMock weatherRepository = new WeatherStationRepositoryMock();
It works fine.
Why does this happen?
How to fix autowiring for my custom repository class?
Upvotes: 0
Views: 3166
Reputation: 17045
@SpringBootApplication
implicitly defines @ComponentScan
, which scans all subpackages for beans.
When you run a test using MockConfig
's, it doesn't scan for beans.
(1) Using @ComponentScan:
@Configuration
@ComponentScan //Make sure MockConfig is below all beans to discover
public class MockConfig {
@Bean
@Real
public WeatherStationService weatherServiceReal() {
return new WeatherStationService();
}
}
(2) or define required beans:
@Configuration
public class MockConfig {
@Bean
@Real
public WeatherStationService weatherServiceReal() {
return new WeatherStationService();
}
@Bean
public WeatherStationRepositoryMock weatherStationRepository() {
return new WeatherStationRepositoryMock()
}
}
Upvotes: 1