spring-boot


Does #WebMvcTest require #SpringBootApplication annotation?


My goal is to migrate a Spring Boot application previously developed with Spring Boot 1.3 to the newest Spring Boot version 1.4. The application consists of several maven modules and only one of them contains class annotated with #SpringBootApplication.
One part of migration is to use #WebMvcTest annotation to efficiently test controllers, and here I get an issue.
Consider an example application from Spring Boot github page. #WebMvcTest annotation works perfectly, because, as far as I understand (after I did several tests), there is a class in the main package annotated with #SpringBootApplication. Note that I follow the same concept as shown in the example above for my own #WebMvcTest tests.
The only difference I see that in my application, controller classes are located in a separate maven module (without #SpringBootApplication annotated class), but with #Configuration and SpringBootConfiguration configurations. If I do not annotate any class with #SpringBootApplication I always get an assertion while testing controller. My assertion is the same as when SampleTestApplication class in the example above modified to have only #EnableAutoConfiguration and #SpringBootConfiguration annotations (#SpringBootApplication is not present):
getVehicleWhenRequestingTextShouldReturnMakeAndModel(sample.test.web.UserVehicleControllerTests) Time elapsed: 0.013 sec <<< FAILURE!
java.lang.AssertionError: Status expected:<200> but was:<404>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81)
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at sample.test.web.UserVehicleControllerTests.getVehicleWhenRequestingTextShouldReturnMakeAndModel(UserVehicleControllerTests.java:68)
How should I deal with that? Should I always have class annotated with #SpringBootApplication in order to run #WebMvcTest tests?
EDIT 1: I did a small maven project with 2 modules and a minimal configuration. It is here. Now, I get NoSuchBeanDefinitionException exception for repository defined in another module. If I configure "full" #SpringBootApplication - everything is fine.
EDIT 2: I modified small test project from EDIT 1 to give an original issue. I was playing with different annotations and added #ComponentScan on configuration class, because I suspected that beans are not registered properly. However, I expect that only #Controller bean (defined in #WebMvcTest(...class)) shall be registered based on magic behind #WebMvcTest behaviour.
EDIT 3: Spring Boot project issue.
Short answer: I believe so.
Long answer:
I believe #WebMvcTest needs to find the SpringBootApplication configuration since WebMvcTest's sole purpose is to help simplify tests (SpringBootApplication would rather try to load the whole world).
In your specific case, since you don't have any in your non-test packages, I believe it also finds SampleTestConfiguration which is annotated with #ScanPackages and somehow loads every beans.
Add the following in src/main/java/sample/test
#SpringBootApplication
public class SampleTestConfiguration {
}
And change your test to this:
#RunWith(SpringRunner.class)
#WebMvcTest(MyController.class)
public class MyControllerTest {
#Autowired
private MockMvc mvc;
#MockBean
private MyService ms;
#Autowired
private ApplicationContext context;
#Test
public void getDataAndExpectOkStatus() throws Exception {
given(ms.execute("1")).willReturn(false);
mvc.perform(get("/1/data").accept(MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isOk()).andExpect(content().string("false"));
}
#Test
public void testMyControllerInAppCtx() {
assertThat(context.getBean(MyController.class), is(not(nullValue())));
}
#Test
public void testNoMyAnotherControllerInAppCtx() {
try {
context.getBean(MyAnotherController.class);
fail("Bean exists");
} catch (BeansException e) {
// ok
}
}
}
#WebMvcTest finds the SpringBootApplication, then load only a limited number of beans (see documentation):
#WebMvcTest will auto-configure the Spring MVC infrastructure and
limit scanned beans to #Controller, #ControllerAdvice, #JsonComponent,
Filter, WebMvcConfigurer and HandlerMethodArgumentResolver. Regular
#Component beans will not be scanned when using this annotation.
WebMvcTest requires SpringBootApplication: WebMvcTest inherits many AutoConfiguration, so it needs SpringBoot to load them. Then it disables many other AutoConfiguration and your Controllers become easily testable.
The whole point of using WebMvcTest is when you have a SpringBootApplication and you wish to make it simpler to test by disabling all beans except Controllers. If you don't have SpringBootApplication, then why use WebMvcTest at all?

Related Links

How to use Apache Shiro for authorization only?
Spring Boot Batch use case for jobParameters and #JobScope/#StepScope over Environment/#ConfigurationProperties when configuring readers and writers?
CORS Origin Spring Boot Jhipster - pre-flight fails
Over writing server port of the application.yml in the command line
Reload javascript after thymeleaf fragment render
Feign/Eureka client not passing X-Forwarded-For header
Spring-Boot, how to start it manually in a servlet 3.0 environment
html form validation using thymeleaf not working spring boot
Spring Boot logging with logback
Spring #Query with principal and ternary operator
Is there a way a spring cloud config client can decrypt cipher text fetched from a config server?
How to get method information at Interceptor preHandle method in spring boot 1.3
Spring Boot Microservices Deployment
Starting Spring Application by merging yml files
Spring Integration with Jackson ObjectMapper and Java 8 Time (JSR-310)
Spring boot not serving static content when Jersey REST is included

Categories

HOME
asp.net
compression
cluster-analysis
pelican
weblogic
cryengine
nltk
ms-application-insights
uml-designer
comments
country-codes
android-webview
element
lambda-calculus
appsettings
background-image
brightway
openscad
alert
beacon
aiml
autologin
spring-webflow
ejb-3.1
serenity-js
ng-tags-input
handle
ppp
windowserror
typeclass
csproj
ios9
opencsv
choco
bootcamp
wit-ai
azure-storage-files
anypoint-studio
file-descriptor
compiled-query
android-graphview
google-cloud-powershell
contenteditable
vpython
risc
django-cors-headers
multivalue
opticalflow
suitesparse
stripes
mongodb-3.3
indoor-positioning-system
access-violation
csc
sprockets
nimbus
vitamio
sbt-proguard
database-administration
3d-rendering
ooad
containstable
jsondoc
nonblocking
lytro
jain-sip
exchange-server-2007
page-flipping
dnvm
properties-file
winforms-interop
callfire
bungeecord
method-overloading
aiff
system.io.packaging
famous-engine
isl
git-subtree
starling-framework
nomachine
imaplib
xml-validation
removeall
junction-table
ncml
jquery-1.8
wxperl
parsec
fileoutputstream
scsf
jqzoom
lgpl
calendarextender
opengl-to-opengles

Resources

Encrypt Message