According to the documentation, @WebMvcTest will pick up @ControllerAdvice as well. However this is not what is happening as I don't see the logic inside of the advise being called. If something is not clear, I can provide a sample.
I'm using spring boot 2.0.1.RELEASE with JUnit 5.
These are the annotations in the BarEndpointTest class:
@SpringJUnitWebConfig
@WebMvcTest(BarEndpoint.class)
Comment From: mbhave
@renannprado We have tests to ensure that this works. From the snippet you've provided it seems like you're narrowing down @WebMvcTest to one controller. I don't think @ControllerAdvice will be picked up in that case.
Providing a minimalistic, complete sample that reproduces the issue will help us determine if this is an actual bug.
Comment From: renannprado
@mbhave thanks a lot. You are right, it's behaving the way I wanted after I removed the controller configuration. Is this documented somehow? Maybe I missed something.
Comment From: mbhave
It is documented here but I guess we could make it a bit more obvious that beans that would normally be scanned by @WebMvcTest are not added if controllers are specified.
Comment From: renannprado
@mbhave the documentation you send is more or less the same as the one I pointed when I opened the issue, right? I believe it would be nice if the behavior regarding controllers is specified :)
Thanks!
Comment From: renannprado
@mbhave I have another question
if I want to do a focused controller + controller advice test, how should I do it? Is putting the @ControllerAdvice class into the controllers property of the annotation the right way to do it?
Comment From: snicoll
@renannprado please review the guidelines for contributing. We prefer to use GitHub issues only for bugs and enhancements. Please ask on StackOverflow or come chat on Gitter.
Comment From: renannprado
Since this is not properly documented, I thought I could ask here - so that this can be documented as well. Thanks for the advice btw, I was really looking for a place to talk about spring, I'll definitely join in the chat.
Comment From: snicoll
From the snippet you've provided it seems like you're narrowing down @WebMvcTest to one controller. I don't think @ControllerAdvice will be picked up in that case.
That's not what I see in the code. If you provide a Class on @WebMvcTest we will stop scanning all controllers but we will still scan controller advices and other related components described in the doc.
@renannprado if you're experiencing a different behaviour, please share a sample that we can clone and run.
Comment From: renannprado
Hey @snicoll
Unfortunately, I longer have the code that can reproduce the issue.
I spend an hour trying to reproduce it again, but I couldn't.
I believe this error had something to do with a @ComponentScan(a.b.c) that we had on the @SpringBootApplication class before, which I moved to its own @Configuration class.
However, moving the @ComponentScan again to the same class didn't reproduce the error.
And since I squashed my commits, I can't run bisect to try to find the scenario where it can be reproduced. I'm sorry. :(
Comment From: jordisan
I have the same problem and it's solved by importing the exception handler class with @Import in the test class.
Comment From: spattanaik75
For new people coming here for this issue:
Check if you have a @ComponentScan annotation in your Springboot Main class. If you do then @WebMvcTest won't work as expected.
@WebMvcTest will still make a call to the Main class and get the list of the Beans so that it can filter some out, and only select @Controller & @ControllerAdvice.
So if your @WebMvcTest needs extra @Componentclasses you have to explicitly mention them using @Import annotation. and for dependencies like services , we should mock them using @MockBean
Example looks like this:
@WebMvcTest(CounterpartyAccountLinkApiControllerImpl.class)
// Lest assume your ControllerAdvice needs an ErrorProperties
// & you want a different SecurityConfig for you usecase
@Import({
ErrorProperties.class,
TestSecurityConfig.class,
})
class MyControllerTest {
@MockBean private MyService myService;
}
Then Modify your Main Application and remove any @ComponentScan overrides and move that to a separate class:
@Configuration
@ComponentScan(basePackages = "com.mypackage")
public class ExternalComponentsConfiguration {}
Comment From: wilkinsona
Thanks, @spattanaik75. This is also described in slightly different terms in the documentation:
If you use a test annotation to test a more specific slice of your application, you should avoid adding configuration settings that are specific to a particular area on the main method’s application class.
The underlying component scan configuration of
@SpringBootApplicationdefines exclude filters that are used to make sure slicing works as expected. If you are using an explicit@ComponentScandirective on your@SpringBootApplication-annotated class, be aware that those filters will be disabled. If you are using slicing, you should define them again.