Issue
While playing around with the javax provider, I have created a spring configuration file with the following two Beans:
@Bean
Provider<Map<Integer, JsonNode>> worldMapDataProvider() {
//code here
}
@Bean
Provider<List<Building>> buildingsDataProvider() {
//code here
}
I am injecting these two beans in two different services like so:
@Resource
private Provider<Map<Integer, JsonNode>> worldMapDataProvider;
@Resource
private Provider<List<Building>> buildingsDataProvider;
The implementation works as expected and my depending controllers also return the data in the anticipated format. Now I wanted to add a few unit-tests for my implementation, by autowiring the providers "into my test-setup".
The configuration for my test-class which worked at the end looks as follows:
@SpringBootTest(classes={ResourceProviders.class, ResourceProviderUtils.class, Beans.class})
class ResourceProvidersTest {
ResourceProvider is what I want to use; this class depends on ResourceProviderUtils which in turn depends on a jackson objectMapper which I have defined in Beans. Thus, the required dependency-chain is ResourceProviders -> ResourceProviderUtils -> Beans
Now, to get to my question.
I was trying to create an annotation-based solution for my test without using @SpringBootTest. To be precise, this is the configuration which I expected to work:
@ExtendWith(SpringExtension.class)
@ComponentScan("{myBasePackage}")
I injected the two Beans exactly the same way as I did in my services with the @Resource annotation. But in the test-case, I get the following exception:
No qualifying bean of type 'java.util.List<{myBasePackage}.game.data.model.economy.buildings.Building>' available
You can see that it is not looking for a bean of type Provider<List>, but for one of type List. I have never delcared such a bean though and as such do not require it anywhere either. I always inject the provider into my services (and this test-case) and access the data using provider.get().
I have a feeling that the provider is implicitly being resolved somehow, but this is just an assumption. Could anybody explain to me what exactly is happening here and why? I would like to get a better understanding of why this is happening with the given configuration.
Solution
@ComponentScan
does not work with @ExtendWith
, use @ContextConfiguration
instead
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes={ResourceProviders.class, ResourceProviderUtils.class, Beans.class})
public class ResourceProvidersTest {
@Autowire ResourceProviders resourceProviders;
@Autowire ResourceProviderUtils resourceProviderUtil;
@Autowire Beans beans;
...
}
Or use @SpringJUnitConfig
; this annotation combines @ExtendWith(SpringExtension.class)
with @ContextConfiguration
@SpringJUnitConfig(classes={ResourceProviders.class, ResourceProviderUtils.class, Beans.class})
public class ResourceProvidersTest {
@Autowire ResourceProviders resourceProviders;
@Autowire ResourceProviderUtils resourceProviderUtil;
@Autowire Beans beans;
...
}
Answered By - Dirk Deyne
Answer Checked By - Terry (JavaFixing Volunteer)