2

I am new to Spring unit Testing. Writing test cases for the Spring rest Controller. When I am writing the test cases in this way

@WebAppConfiguration
@ContextConfiguration(locations = {"file:src/test/resources/applicationContext.xml"})
public class TaskControllerIntegrationTest extends AbstractTransactionalTestNGSpringContextTests {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext wac;

    @BeforeClass
    public void setUp() {

        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void testGetAllTasks() throws Exception {

        mockMvc.perform(get("/v1/testSessions/{testSessionId}/tasks", 1l))
                .andExpect(status().isOk());



    }

}

I am getting the testcase failed don't know why :( while If i initialize the MockMvc using the standalone controller it works perfect and my allTest cases are passes.The setup for the MockMvc using standalone controller is in this way. It's for unit testing:

@Mock
    private TaskService taskServiceMock;

    @InjectMocks
    private TaskController taskController;


    private MockMvc mockMvc;

    @Spy
    List<Task> allTasks = new ArrayList<Task>();

   /* @Spy
    List<TaskSessionModel> taskSessionModelList = new ArrayList<TaskSessionModel>();*/

    @BeforeClass
    public void setUp() {
        //    Mockito.reset(taskServiceMock);
        MockitoAnnotations.initMocks(this);
        //       taskSessionModelList = getAllTaskSessionModels();
        allTasks = getAllTasks();
        this.mockMvc = MockMvcBuilders.standaloneSetup(taskController).build();
    }

    @Test
    public void testGetAllTasks() throws Exception {

        //  when(taskSessionDao.findAllByTestSession(1l)).thenReturn(taskSessionModelList);
        when(taskServiceMock.getAllTasks(1l)).thenReturn(allTasks);

        mockMvc.perform(get("/v1/testSessions/{testSessionId}/tasks", 1l)
                .accept(MediaType.APPLICATION_JSON_VALUE))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
                .andExpect(jsonPath("$", hasSize(2)))
                .andExpect(jsonPath("$[0].name", is("Average")));


        List<Task> expTaskList = taskController.getAllTasks(1l);
        verify(taskServiceMock, times(2)).getAllTasks(1l);
        verifyNoMoreInteractions(taskServiceMock);
        assertEquals(allTasks, expTaskList);

    }

But if i write the same unit test by using the WebApplicationContext .. I will get error and test cases will failed :

java.lang.AssertionError: Status 
Expected :200
Actual   :500
 <Click to see difference>


    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
    at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:654)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:152)
    at com.blueoptima.dt.controller.TaskControllerIntegrationTest.testGetAllTasks(TaskControllerIntegrationTest.java:46)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
    at org.testng.internal.MethodInvocationHelper$1.runTestMethod(MethodInvocationHelper.java:200)
    at org.springframework.test.context.testng.AbstractTestNGSpringContextTests.run(AbstractTestNGSpringContextTests.java:171)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeHookable(MethodInvocationHelper.java:212)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:707)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
    at org.testng.TestRunner.privateRun(TestRunner.java:767)
    at org.testng.TestRunner.run(TestRunner.java:617)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
    at org.testng.TestNG.run(TestNG.java:1057)
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:74)
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:124)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

I don't know what's the wrong? I tried almost all the solution for the WebApplicationContext setup(see the first code) it's in the same way as I see .. on this website and mostly configuration in spring official website and other after googling it but still error remains same? Have a look into this ! Cheers !!

shiva
  • 730
  • 8
  • 25
  • Output the response by modifying your mockMvc like this: System.out.println(mockMvc.perform(get("/v1/testSessions/{testSessionId}/tasks", 1l)).getResponse().getContentAsString()); – Journeycorner Aug 18 '16 at 18:24
  • there us no getResponse() after this .. I am getting error while adding it – shiva Aug 18 '16 at 18:31
  • Since your are getting a response status, there also should be a response body. Set a breakpoint inside your controller, look for null values. You could also try to use JUnit(annotations) instead of TESTNG. – Journeycorner Aug 18 '16 at 18:40
  • I read so Many blogs that testNg is better than Junit4. I am trying to do integration testing end to end . Let me check what's the wrong I am doing here. Thanks for the help. – shiva Aug 18 '16 at 18:52
  • in the controller i did @Autowired private TaskService taskService; and taskService itself is null . what to do for it ? can you please tell me ? i am very new to unit testing and Integration testing .. it's integration testing so I can't use mockito here .. – shiva Aug 18 '16 at 18:56

1 Answers1

0

Go back one step, forget about all Spring and technology stuff and ask yourself what you want to achieve with the tests?

If you want to do a real integration tests, don't mock controllers or services, so the following code makes no sense:

@Mock
private TaskService taskServiceMock;

That should be the problem in your setup. Remove all mocks instead of MockMvc and try again. Take a cup of coffee and read the official documentation, it will teach you all the details including setting up a in-memory-database and setting up the Spring TestContext Framework.

To access your controllers, you have two choices, depending on how deep the tests shall go.

Community
  • 1
  • 1
Journeycorner
  • 2,474
  • 3
  • 19
  • 43
  • No .. i think you misunderstood ! second code is for unit testing wo I am mocking the service class object with the use of mockito... that's working fine ..all test cases are passed by using standalone setup .. no errors ! in the first code I am doing integration testing .. end to end testing of the code.... with the use of webapplicationcontext setup and There is I am getting error while calling the url through mockMvc. it's gives internal server error. If i call the same method by creating the object of controller it's works perfect :) ..there is some issue in that ? Please look into that – shiva Aug 19 '16 at 09:00
  • If you want I can add the code of applicationContext.xml as well ... but I think there is no need because after creating the instance of controller using @Autowired private TaskController taskController , it works fine. So something wrong with the mockMvc .. i check by putting debugging points that objects are getting created in mockmvc and webapplicationContext but then what's the error I didn't get .. so I need help ! – shiva Aug 19 '16 at 09:02
  • Is it working when you start the application manually? Your problem is obviously that the service inside the can't be autowired. Try "@RunWith(SpringRunner.class)" as described here: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#spring-mvc-test-server. If it still doesn't work, try to use JUnit - you can switch back later, just to make sure it is not the source of error. – Journeycorner Aug 19 '16 at 09:06
  • Yes it's workign fine when I start the application using a web server .. and in case of standalone setup also it works .. okay let me try the @RunWith(springjunit4runner.class ) and I will let you know – shiva Aug 19 '16 at 09:08
  • Do you have some emailid .. / Gmail so that I can mesaage you ? – shiva Aug 19 '16 at 09:09
  • @RunWith(SpringRunner.class) this dependency didn't get resolved ? which dependency should i add ? is it different from @RunWith(SpringJUnit4ClassRunner.class) – shiva Aug 19 '16 at 11:12
  • Let me google that for you... http://stackoverflow.com/a/13933357/3698894 – Journeycorner Aug 19 '16 at 11:49