0

I have two implementations for a given interface both are annotated with @Component.

One implementation is in src/main -> IImplementationCore.java Other implementation is in src/test -> IImplementationTest.java

I have a test class ABCTest.java in src/test which is annotated with

@RunWith(SpringRunner.class), @SpringBootTest, @ContextConfiguration, @ComponentScan, @EnableAutoConfiguration

I want this ABCTest.java to inject IImplementationCore while running the test. But it is injecting IImplementationTest.java.

package structure:

  • src
    • main
      • package
        • IImplementationCore.java
    • test
      • package
        • IImplementationTest.java
      • package2
        • ABCTest.java

Solution I know:

  • Annotating @Primary for IImplementationCore.java resolves the issue.

I somehow do not like to force something as primary because it is being annotated as primary due to some bean conflict from src/test but not due to some real conflict in core implementations. what are my other options? What I am looking for is, is there a way to only consider beans from src/main but not from src/test? Or is there any better way?

Deepak
  • 962
  • 4
  • 17
  • 38
  • you can use a Qualifier – Stultuske Mar 15 '22 at 08:34
  • are you saying to add qualifier in ABCTest.java while autowiring? – Deepak Mar 15 '22 at 08:37
  • Does this answer your question? [Autowiring conflict in spring core with the xml configuration](https://stackoverflow.com/questions/55572845/autowiring-conflict-in-spring-core-with-the-xml-configuration) – Med Elgarnaoui Mar 15 '22 at 08:42
  • I am saying you could google to find out what a Qualifier is and how it works. A Qualifier is used to decide between implementations. – Stultuske Mar 15 '22 at 08:42
  • @MedElgarnaoui he is using annotations, not xml – Stultuske Mar 15 '22 at 08:43
  • @Stultuske this post mentioned also the Qualifier annotation, take a look, thanks for your precision – Med Elgarnaoui Mar 15 '22 at 08:45
  • sure for Qualifier. I gave names for those components saying Component(value="core") and Component(value="test"). But when I tried to use Qualifier, it shows compile error saying "cannot find method value". However Named annotation works and I used Named("core") but it still is injecting Component(value="test"). confused. – Deepak Mar 15 '22 at 08:56
  • i used the wrong import of Qualifier, however after fixing, still not injecting the right bean – Deepak Mar 15 '22 at 09:28
  • I have also tried to excludeFilters in component scan, so i can exclude the package scan of this unwanted test bean, still is not helping. – Deepak Mar 15 '22 at 09:30

1 Answers1

0

You could use @Profile annotation on your implementations. It will load a bean only if specified profile/s are currently active.

@Component
@Profile({"a", "b"})
public IImplementationCore implements YourInterface {
}

Specify the profiles for test implementation the same way.

If this test class is very specific, like being the only one needing implementation core, you can use @ActiveProfiles on it to activate profile different from current for this test class only.

//other annotations
@ActiveProfiles("a")
public TestClass {
}
Chaosfire
  • 4,818
  • 4
  • 8
  • 23