17

I write this test class :

@ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" })
public class CandidateControllerTest {

        @Mock(name = "candidateService")
        private CandidateService candidateService;

        @InjectMocks
        private CandidateMenuController candidateMenuController = new CandidateMenuController();


        @Autowired
        WebApplicationContext wac;

        MockMvc mockMvc;


        @Before
        public void before() {



            mockMvc = MockMvcBuilders.webApplicationContextSetup(wac).build();
         }
    }

But:

After code execution I see next trace:

java.lang.IllegalArgumentException: WebApplicationContext is required
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.test.web.server.setup.InitializedContextMockMvcBuilder.<init>(InitializedContextMockMvcBuilder.java:39)
    at org.springframework.test.web.server.setup.MockMvcBuilders.webApplicationContextSetup(MockMvcBuilders.java:73)
    at controllers.CandidateControllerTest.before(CandidateControllerTest.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

What Would I do for fixing my problem?

UPDATE

I change code:

@ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" })
@WebAppConfiguration
public class CandidateControllerTest {

    @Mock(name = "candidateService")
    private CandidateService candidateService;

    @InjectMocks
    private CandidateMenuController candidateMenuController = new CandidateMenuController();

    @Autowired
    WebApplicationContext wac;

    MockMvc mockMvc;

    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);

        // this.mockMvc =
        // MockMvcBuilders.webAppContextSetup(this.wac).dispatchOptions(true).build();

         mockMvc = MockMvcBuilders.webApplicationContextSetup(wac).build();

    }
...
}

trace:

java.lang.IllegalArgumentException: WebApplicationContext is required
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.test.web.server.setup.InitializedContextMockMvcBuilder.<init>(InitializedContextMockMvcBuilder.java:39)
    at org.springframework.test.web.server.setup.MockMvcBuilders.webApplicationContextSetup(MockMvcBuilders.java:73)
    at controllers.CandidateControllerTest.before(CandidateControllerTest.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Tom
  • 3,006
  • 6
  • 33
  • 54
gstackoverflow
  • 36,709
  • 117
  • 359
  • 710
  • more information http://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html –  Oct 02 '13 at 11:10
  • You seem to lack a lot of basic understanding in Spring and Testing in general. Add a @RunWith annotation or extend one of the spring base classes. (See modified answer). This is also explained in the reference guide (the link I already put in the answer). – M. Deinum Oct 02 '13 at 12:14

7 Answers7

15

There is no WebApplicationContext only an ApplicationContext unless you add the @WebAppConfiguration to your test class.

@ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class CandidateControllerTest { ... }

Instead of the @RunWith annotation you can also extend one of springs convenience classes.

@ContextConfiguration(locations = { "classpath:/test/BeanConfig.xml" })
@WebAppConfiguration
public class CandidateControllerTest extends AbstractJUnit4SpringContextTests { ... }

Links

  1. WebAppConfiguration javadoc
  2. Reference Guide
Siddharth
  • 9,349
  • 16
  • 86
  • 148
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
12

I had the same issue using TestNG & Mockito.

Turns out wac isn't autowired and available in @BeforeTest methods but is in @Test methods.

I moved this

mockMvc = MockMvcBuilders.webApplicationContextSetup(wac).build();

to an @Test method and presto, it works!

Here's the link I found with the solution: http://forum.spring.io/forum/spring-projects/web/737624-problem-with-autowiring-webapplicationcontext-with-annotationconfigcontextloader

banan3'14
  • 3,810
  • 3
  • 24
  • 47
obi1
  • 314
  • 2
  • 6
1

WebApplicationContext is required and NullPointerException are the most confusing errors I faced as beginner to TestNG and Spring Test Framework. These are happened due to simple mistakes like forget to `extends AbstractTestNGSpringContextTests1 etc. To avoid those errors I'll give you the code template I use.

@Test
@WebAppConfiguration
@ContextConfiguration(classes = WebConfig.class) //You can use your xml too
public class YourControllerTest extends AbstractTestNGSpringContextTests {
    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;


    @Test
    public void getEmailVerificationTest() throws Exception {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();

        this.mockMvc.perform(get("/home")
                .accept(MediaType.ALL))
                .andExpect(status().isOk())
                .andExpect(view().name("home/index"));
    }
}

This is sample code to test home page. If you are Beginner, an error occur such as I mentioned above, first check whether extends AbstractTestNGSpringContextTests and this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); are in the proper places.

Another thing is you can use @BeforeMethod annotation to stop repeating this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build(); in each module. You should have add @BeforeMethod like Below.

    @BeforeMethod
    public void setWac(){
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }
Menuka Ishan
  • 5,164
  • 3
  • 50
  • 66
0

try to do like this

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.javainuse.test.SpringBootHelloWorldTests;

public class TestControllerTest extends SpringBootHelloWorldTests {

    @Autowired
    private WebApplicationContext webApplicationContext;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }

    @Test
    public void testEmployee() throws Exception {
        mockMvc.perform(get("/employee")).andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"))
                .andExpect(jsonPath("$.name").value("emp1")).andExpect(jsonPath("$.designation").value("manager"))
                .andExpect(jsonPath("$.empId").value("1")).andExpect(jsonPath("$.salary").value(3000));

    }

}

and the SpringBootHelloWorldTests is as below

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.javainuse.SpringBootHelloWorldApplication;


@RunWith(SpringRunner.class)
@SpringBootTest(classes=SpringBootHelloWorldApplication.class)
public class SpringBootHelloWorldTests {

    @Test
    public void contextLoads() {
    }

}

and this is the SpringBootHelloWorldApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootHelloWorldApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootHelloWorldApplication.class, args);
    }
}
Bhaskara Arani
  • 1,556
  • 1
  • 26
  • 44
  • The question wasn't about Spring Boot but rather Spring without Spring Boot. Answering this question with a Spring Boot way of doing a test won't help. – M. Deinum Apr 23 '19 at 17:03
0

For me the issue was not having the following maven dependencies:

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
        <scope>test</scope>
    </dependency>

But I was injecting the context like this:

@Inject
protected WebApplicationContext webApplicationContext;
protected MockMvc mockMvc;

@Before
public void before() {
    this.mockMvc = webAppContextSetup(this.wac).build();
}
piotr szybicki
  • 1,532
  • 1
  • 11
  • 12
-1

Add below annotation for your setup.

@BeforeClass(dependsOnMethods={"springTestContextPrepareTestInstance"})

https://stackoverflow.com/a/16474433/2948001 by romeara

TuGordoBello
  • 4,350
  • 9
  • 52
  • 78
-1

For me the issue was resolved when I added the RunWith annotation. Please see below:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK,classes = {SampleConfig.class})
public class SampleTest {
TuGordoBello
  • 4,350
  • 9
  • 52
  • 78