Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Test returning 404 instead of 200 in testing Rest API in Spring Boot

To put simply, my controller is like this :

@RestController
@RequestMapping(value = "/assetservice/rest/v1.0/")
public class LibrarySearchController {


    private LibraryService libServices;
    @Autowired
    public LibrarySearchController(LibraryService libraryService)
    {
        this.libServices = libraryService;
    }

    /**
     * Get Libraries for given Collection ids 
     * @param collectionIds
     * @return List<MediaLibraryDetail>
     */

    @RequestMapping("libraries/search/")

    public MediaLibraries getLibraryTree(@RequestParam(value="collectionIds", defaultValue="")String[] collectionIds, @RequestParam(value="offset",required=false,defaultValue = "0") int offset, @RequestParam(value="limit",required=false
            ,defaultValue = "10") int limit) throws Exception{


        MediaLibraries mediaLibraries = libServices.getAllLibraries(collectionIds, offset, limit);
        System.out.println(mediaLibraries);
        if(mediaLibraries.getLibraryElements()== null)
            throw new InvalidCollectionIdFoundException();

        return mediaLibraries;

    }
}

Basically what it is doing is taking some inputs like collectionId (an array of some numbers) , some offset and some limit and trying to give back some data.

To test this controller , I have written a test using spring test framework. I have simplified the test for asking the question here.

@RunWith(SpringRunner.class)
@WebMvcTest(value = LibrarySearchController.class, secure = false)
public class LibrarySearchControllerMockMvcTest {

//Some other code  was here
@Test
    public void testVerifyRetrievedMediaLibrariesJson() throws Exception{


        MediaLibraries mediaLibraries = createMediaLibrariesObject();//creates mediaLibraries Object; code not shown
        given(libraryService.getAllLibraries(collectionId,offset,limit)).willReturn(mediaLibraries); //mocking the service

        mvc.perform(get("assetservice/rest/v1.0/libraries/search/?collectionIds=418A70D0F31010038152080020F03012&offset=0&limit=1"))

                .andDo(print())
                .andExpect(status().isOk());

    }
}

It shows 404 error. I was expecting 200. Why ?

If you see the second line of error PageNotFound: No mapping found for HTTP request with URI [assetservice/rest/v1.0/libraries/search/] in DispatcherServlet with name ''

Is it because of this ? How to resolve ? The error is :

2017-05-01 20:49:51.252  INFO 13892 --- [           main] s.m.c.LibrarySearchControllerMockMvcTest : Started LibrarySearchControllerMockMvcTest in 3.98 seconds (JVM running for 5.356)
2017-05-01 20:49:51.346  WARN 13892 --- [           main] o.s.web.servlet.PageNotFound             : No mapping found for HTTP request with URI [assetservice/rest/v1.0/libraries/search/] in DispatcherServlet with name ''

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = assetservice/rest/v1.0/libraries/search/
       Parameters = {collectionIds=[418A70D0F31010038152080020F03012], offset=[0], limit=[1]}
          Headers = {}

Handler:
             Type = null

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 404
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = assetservice/rest/v1.0/libraries/search/
       Parameters = {collectionIds=[418A70D0F31010038152080020F03012], offset=[0], limit=[1]}
          Headers = {}

Handler:
             Type = null

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 404
    Error message = null
          Headers = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

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


    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 com.cdk.dmg.services.mediaasset.controller.LibrarySearchControllerMockMvcTest.testVerifyRetrievedMediaLibrariesJson(LibrarySearchControllerMockMvcTest.java:109)
    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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

2017-05-01 20:49:51.377  INFO 13892 --- [       Thread-2] o.s.w.c.s.GenericWebApplicationContext   : Closing org.springframework.web.context.support.GenericWebApplicationContext@550dbc7a: startup date [Mon May 01 20:49:48 IST 2017]; root of context hierarchy

Process finished with exit code -1

My application class is:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

and code runs fine. Only error is shown while testing.

like image 315
Number945 Avatar asked May 01 '17 15:05

Number945


People also ask

What does SpringBootTest annotation do?

The @SpringBootTest annotation is useful when we need to bootstrap the entire container. The annotation works by creating the ApplicationContext that will be utilized in our tests. We can use the webEnvironment attribute of @SpringBootTest to configure our runtime environment; we're using WebEnvironment.


1 Answers

Adding a slash at the beginning of the URL will solve this problem:

 mvc.perform(get("/assetservice/[...]")

Spring test probably takes the provided URL as-is when trying to match it to an endpoint and because of this can't find any matching endpoints in this case.

like image 71
Riiverside Avatar answered Sep 28 '22 06:09

Riiverside