I have a spring-boot app that now needs to support multiple Object stores and selectively use the desired store based on the environment. Essentially what i have done is create an interface that each store repository then implements.
I have simplified the code for the examples. I have created 2 beans for each store type based on the spring profile determining the env:
@Profile("env1") @Bean public store1Sdk buildClientStore1() { return new store1sdk(); } @Profile("env2") @Bean public store2Sdk buildClientStore2() { return new store2sdk(); }
in the service layer I have autowired the interface and then in the repositories i have used @Profile to specify which instance of the interface to use.
public interface ObjectStore { String download(String fileObjectKey); ... } @Service public class ObjectHandlerService { @Autowired private ObjectStore objectStore; public String getObject(String fileObjectKey) { return objectStore.download(fileObjectKey); } ... } @Repository @Profile("env1") public class Store1Repository implements ObjectStore { @Autowired private Store1Sdk store1client; public String download(String fileObjectKey) { return store1client.getObject(storeName, fileObjectKey); } }
When I start the application with the configured “env” this actually runs as expected. however when running the test I get the “no qualifying bean of type ObjectStore. expected at least 1 bean which qualifies as autowire candidate.”
@ExtendWith({ SpringExtension.class }) @SpringBootTest(classes = Application.class) @ActiveProfiles("env1,test") public class ComposerServiceTest { @Autowired private ObjectHandlerService service; @Test void download_success() { String response = service.getObject("testKey"); ... } }
As noted in the @ActiveProfile on the test class there are some other environments e.g. dev,test,prod. I have tried playing around with Component scan, having impl and interface in the same package, etc, to no success. I feel like I am missing something obvious with the test setup. But could be something with my overall application config? my main aim with the solution is to avoid having something a long the lines of
if (store1Sdk != null) { store1Sdk.download(fileObjectKey); } if (store2Sdk != null) { store2Sdk.download(fileObjectKey); }
Advertisement
Answer
Try @ActiveProfiles({"env1", "test"})
.
Activate multiple profiles using @ActiveProfiles
and specify profiles as an array.