I am trying to create spring-mvc tests using Spring 3.2.1. Following some tutorials, I thought this would be straight-forward.
Here is my test:
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( loader = AnnotationConfigContextLoader.class, classes = { JpaTestConfig.class } )
@WebAppConfiguration
public class HomeControllerTest {
@Resource
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Test
public void testRoot() throws Exception {
mockMvc.perform(get("/").accept(MediaType.TEXT_PLAIN)).andDo(print())
// print the request/response in the console
.andExpect(status().isOk()).andExpect(content().contentType(MediaType.TEXT_PLAIN))
.andExpect(content().string("Hello World!"));
}
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
Here is my relevant pom.xml:
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>
I have the following test configuration class:
@Configuration
@EnableTransactionManagement
@ComponentScan( basePackages = { "com.myproject.service", "com.myproject.utility",
"com.myproject.controller" } )
@ImportResource( "classpath:applicationContext.xml" )
public class JpaTestConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
...
}
// various other services/datasource but not controllers
}
It is my understanding that adding @WebAppConfiguration
will force Spring to inject it. But when I run this test from within Eclipse I get:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.web.context.WebApplicationContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:967) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:837) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:749) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
Update - I had to change my Test Java Configuration class
@Configuration
@EnableWebMvc
@ComponentScan( basePackages = { "...." } )
@EnableTransactionManagement
@ImportResource( "classpath:applicationContext.xml" )
public class JpaTestConfig extends WebMvcConfigurationSupport {
However, the problem is now that I can call my REST service, but it is invoking some other services, including database calls. What is the preferred way to just test the call and a mocked response. I would like to test valid and invalid conditions.
Annotation Type WebAppConfiguration @WebAppConfiguration is a class-level annotation that is used to declare that the ApplicationContext loaded for an integration test should be a WebApplicationContext .
The main difference between @SpringBootTest and @WebMvcTest annotations is that @SpringBootTest annotation will start full application context. Whereas @WebMvcTest annotation will make Spring Framework create application context with a limited number of beans(only those related to Web Layer).
public static DefaultMockMvcBuilder webAppContextSetup(WebApplicationContext context) Build a MockMvc instance using the given, fully initialized (i.e., refreshed) WebApplicationContext . The DispatcherServlet will use the context to discover Spring MVC infrastructure and application controllers in it.
The MockMvcBuilders. standaloneSetup() allows to register one or more controllers without the need to use the full WebApplicationContext .
In my case problem has been solved by replacing:
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = { ... })
with
@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class, classes = { ... })
Notice the Web in the loader class name. With the previous loader, the GenericApplicationContext
has been injected despite @WebAppConfiguration
annotation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With