Closed michael-simons closed 7 years ago
Javadoc:
@Component that can be used when a bean is intended only for tests, and should be excluded from Spring Boot's component scanning.
Documentation:
To help prevent this, Spring Boot provides @TestComponent and @TestConfiguration annotations that can be used on classes in src/test/java to indicate that they should not be picked up by scanning.
What do you expect based on the doc?
Exactly the example above: Annotating a pojo in src/test/java
with only @TestComponent
with the result that it gets picked up during test, not that I have to use both @Component
and @TestComponent
.
If I have an @Component
inside src/test/java
, it get's picked up only during tests anyway, not during normal start. I cannot annotate any component inside src/main/java
with @TestComponent
having spring-boot-starter-test
as test dependency.
I am not following, the doc states that it will not be picked up by component scan. Why do you want it to be picked up all the sudden then? @TestConfiguration
aren't picked up by component scan either ...
Perhaps we could turn that one into a documentation enhancement. I am not excluding that @philwebb had something else in mind that I didn't get so it's certainly a good use of our time.
Sadly, you gave up when I just understood the purpose of @TestComponent
.
I'd recommend you separate it a bit from @TestConfiguration
in the docs and state that @TestComponent
facilitate the creation of @TestConfiguration
.
(TBH: I wonder if @TestComponent
belongs into the reference at all or should only be part of JavaDoc)
Thanks, @snicoll for the good discussion. Got it now.
The conversation on gitter was going in circles. If we've added that in the doc explicitly, I guess there's a reason I am missing anyway so we'll follow-up here for sure.
See also #6769 (in particular https://github.com/spring-projects/spring-boot/issues/6769#issuecomment-278794709)
Hey,
just a quick feedback from my colleague here, I tried to asked the questions about 41.3.2 in the docs as open as possible and he expressed the same expectations as I: @TestComponent
would have the same visible result as @TestConfiguration
(by visible result we mean have an impact in the application context, that is add to the configuration, appearing as bean (regardless if its component-scan or something else)).
I think the dualism of @TestConfiguration
is what causes or confusion with @TestComponent
. Although @TestConfiguration
is not picked by component scan, it has an impact.
Very good change in the docs! Thanks.
I got the same confusion. If @TestComponent just filters out the component from the test context, I don't understand where it is used, so perhaps it would be better to focus on explaining when do you need such a feature. If I understand correctly by reading the docs, one uses @TestComponent to annotate a class that might be excluded by default and selectively importable via its TestConfiguration parent @Import for particular testclasses you need it. But then, whats the point on making it a @XComponent at all? Does @Import only accept configuration @XComponent classes perhaps? Or it is maybe because that way we don't need to remove annotations that signal the purpose of the class like Stereotypes in order to exclude them from the component scanning?
I mean imagine I have a custom class AuxiliarHelperForMyTests class, and I don't annotate it with either @Component or @TestComponent. It exactly behaves as the description of @TestComponent, so what is exactly the purpose of @TestComponent annotation, what does it give me as extra value?
A noted in the commit that closed this issue, @TestComponent
is really an implementation detail so you should not be using it directly. It exists to enable the functionality provided by @TestConfiguration
which is described in the documentation.
If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.
Ahh that explains why any mention was removed from latest documentation. Anyway, I did a deep testing and I will expose the case in the way my mind would have understood it, in case you accept the suggerence for documentation or anyone else comes to this ticket as I did. Please remove it if you consider it inappropiate. And excuses for mistaking the workflow if that is the case in beforehand:
If
you have classes in test classpath that you want to explictly mark as Stereotypes (@Component
) or @Configuration
, but you don't want them loaded accross all tests by the component scanning,
the solution is marking them additionally as @TestComponent
and @TestConfiguration
. This is the benefit (1) I see of these 2 new annotations.
Then you can use @Import
on any particular test class to import any of both (BTW, it was hard to find out that Import works on Components as if they were @Bean
s from a @Configuration
class).
The curious thing is that @Import
does not require classes to be annotated with either @Component
or @Configuration
to load them,
hence the special @TestX
marker versions are not justified as a device to exclude from classpath but mark as importable.
Remember static inner classes are not part of component-scanning when found within test classes, so using previous annotations as static inner classes inside a test class:
@TestConfiguration
is loaded as if it was @Configuration
, with the difference that it does not override primary configuration (i.e, if you use @Configuration
, then you'll miss beans exposed in production).
This is the benefit (2) I see, specific to @TestConfiguration
.@Component
is not automatically picked within test classes since Spring Boot 1.4, due to TestTypeExcludeFilter
excluding them, and neither is @TestComponent
.
In this case, marking the component with @TestComponent
is only useful for clarity purposes, for the component requires an @Import
on the outer class to be picked anyways,
and import does not require any annotation on imported class in order to process it as a configuration/component class as explained before.
Hi,
hopefully I'm not doing anything wrong here. I assume that
@TestComponent
should be picked up when running tests with@SpringBootTest
without further ado, but neither thistogether with
nor this (nested version)
works. Both fail with
org.springframework.beans.factory.NoSuchBeanDefinitionException
. Sample project is attached: InitializrSpringbootProject.zip Tested with 1.4.0, 1.4.3 and 1.5.1.Maybe it's a documentation issue, but I don't see my error…