Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@ComponentScan on a test class is processed when creating a test context but is not included in the context's cache key #31577

Closed
springframeworkguru opened this issue Jul 5, 2022 · 5 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@springframeworkguru
Copy link

I have the following test, which works okay under Maven & Spring Boot 2.x.

AuthorDao bean fails to load when running under Maven and Spring Boot M3.

Works as expected when executing test under IntelliJ w/ Spring Boot M3.

This only is failing when running in a Maven context.

@ActiveProfiles("local")
@DataJpaTest
@ComponentScan(basePackages = {"guru.springframework.jdbc.dao"})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class AuthorDaoIntegrationTest {

    @Autowired
    AuthorDao authorDao;

    @Test
    void testGetAuthor() {

        Author author = authorDao.getById(1L);

        assertThat(author).isNotNull();

    }
}

Error:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'guru.springframework.jdbc.dao.AuthorDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1779) ~[spring-beans-6.0.0-M4.jar:6.0.0-M4]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1338) ~[spring-beans-6.0.0-M4.jar:6.0.0-M4]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1292) ~[spring-beans-6.0.0-M4.jar:6.0.0-M4]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:717) ~[spring-beans-6.0.0-M4.jar:6.0.0-M4]
	... 72 common frames omitted

Gist of full build console output.

See complete project here. Note: Use branch "author-add-dao". (project is setup to run against local MySQL db using profile 'local' - sql init scripts under /src/scripts)

  • Oracle OpenJDK 17.0.2
  • Spring Boot 3.0.0-M3
  • Maven 3.8.1
  • Maven Surefire 2.22.2 (also tested with 3.0.0-M7, no change)
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jul 5, 2022
@wilkinsona wilkinsona self-assigned this Jul 6, 2022
@wilkinsona
Copy link
Member

Thanks for the report and sample.

which works okay under Maven & Spring Boot 2.x

It doesn't for me. After changing the JPA imports to javax.*, I see the same failure with Spring Boot 2.7.1 when running the tests with Maven.

I believe the problem is due to context caching and test ordering. The gist shows that MySQLIntegrationTest is run first and a context is created for it. It passes. AuthorDaoIntegrationTest is then run and it reuses the same context. It fails as the context created for MySQLIntegrationTest does not include AuthorDaoImpl.

The use of @ComponentScan on a test class is unusual and it isn't something that we intentionally support. It works due to Boot's ImportsContextCustomizer which is intended to allow the use of @Import on test classes. A side-effect of how this is implemented is that @ComponentScan is picked up too. @ComponentScan isn't considered when creating the cache key for the context which results in AuthorDaoIntegrationTest reusing the context that was created for MySQLIntegrationTest despite the fact that they should contain different beans.

I'd like to discuss this with the rest of the team so that we can decide what to do. We could update the code that generates the cache key to consider @ComponentScan. Alternatively, we may be able to find a different solution for @ImportsContextCustomizer which would prevent @ComponentScan from being unintentionally picked up.

@wilkinsona wilkinsona removed their assignment Jul 6, 2022
@wilkinsona wilkinsona added this to the 2.6.x milestone Jul 6, 2022
@wilkinsona wilkinsona added type: bug A general bug for: team-meeting An issue we'd like to discuss as a team to make progress and removed status: waiting-for-triage An issue we've not yet triaged labels Jul 6, 2022
@wilkinsona wilkinsona changed the title Spring Boot M3 - Dep Fails to Load w/@DataJpaTest under Maven (okay w/Intellij & Spring Boot 2.x) @ComponentScan on a test class is processed when creating a test context but is not included in the context's cache key Jul 6, 2022
@springframeworkguru
Copy link
Author

Thanks @wilkinsona. My goal is use the @DataJpaTest splice and only add the AuthorDaoImpl bean for the test. Is there an alternative approach I should use?

I also verified this is failing under my previous SB version of 2.5.3. (I swear it was working under Maven then too! LOL)

@wilkinsona
Copy link
Member

You can use @Import(AuthorDaoImpl.class)

@philwebb
Copy link
Member

philwebb commented Jul 6, 2022

We're going to try and support @ComponentScan. We'll update ImportsContextCustomizerFactory to detect it and ImportsContextCustomizer to include it as part of the cache key.

@philwebb philwebb removed the for: team-meeting An issue we'd like to discuss as a team to make progress label Jul 6, 2022
@springframeworkguru
Copy link
Author

Thanks @philwebb.

And thanks @wilkinsona - I had assumed @Import was for configuration classes. But works like a champ on the component too. Appreciate the tip!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

4 participants