1

Background: Search form in a webapp, with an auto-complete/suggestion. Using jQuery's autocomplete, suggestions are shown after typing a few characters. These suggesitons are retrieved as JSON data from one of the webapp's controllers.

Issue: I am testing the application via the HtmlUnit Integration of Spring Test, which works fine for Text/Html Pages, but for the JSON responses here, the setup seems to fail (see error below).

Manually testing (the actual webapp) via Browser works and fetching JSON from "real" pages works as well ( see "json()" test) -> Should testing JSON responses work via HtmlUnit / Spring Test setup and if yes, what am I doing wrong?

Update (2017-06-21): Using

@ResponseBody String

and building the JSON "manually" (not letting Spring automagically doing it) works; not really what I wanted, but at least I can properly test it this way ...

Test:

package my.project;

import com.gargoylesoftware.htmlunit.*;
import org.junit.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.*;
import org.springframework.test.*;
import org.springframework.web.context.support.GenericWebApplicationContext;

import javax.servlet.ServletException;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestWebAppConfig.class,
    // avoid context caching
    MyControllerIT.class})
@WebAppConfiguration
public class MyControllerIT {

    protected static final String SERVER_URL = "http://localhost";
    protected WebClient webClient;
    protected MockHttpServletRequest request;
    protected MockHttpServletResponse response;

    @Autowired
    protected GenericWebApplicationContext webApplicationContext;

    @Before
    public void setUp() throws Exception {

        this.request = new MockHttpServletRequest();
        this.request.setServerName("Gondor.Osgiliath");
        this.response = new MockHttpServletResponse();
        this.webClient = this.initClient();
    }

    protected final WebClient initClient() throws ServletException {

        DefaultMockMvcBuilder mockMvcBuilder = MockMvcBuilders.webAppContextSetup(this.webApplicationContext);
        MockMvc mockMvc = mockMvcBuilder.build();

        WebClient webClient = new WebClient();
        webClient.setWebConnection(new MockMvcWebConnection(mockMvc));
        return webClient;
    }

    // https://stackoverflow.com/questions/2932857/html-handling-a-json-response
    @Test
    public void json() throws Exception {

        webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER, "some.proxy", 7890);
        Page page = webClient.getPage("https://stackoverflow.com/users/flair/97901.json");

        WebResponse webResponse = page.getWebResponse();
        String contentType = webResponse.getContentType();

        String contentAsString = webResponse.getContentAsString();
    }

    @Test
    public void suggestShouldReturnJSON() throws Exception {

        Page page = webClient.getPage(SERVER_URL + MyController.SUGGEST_URL + "?term=asdf");

        WebResponse webResponse = page.getWebResponse();
        String contentType = webResponse.getContentType();

        String contentAsString = webResponse.getContentAsString();
    }

    @Test
    public void suggestShouldReturnJSONViaMockMvc() throws Exception {

        MockMvc springMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();

        ResultActions resultActions = springMvc.perform(MockMvcRequestBuilders
            .get(MyController.SUGGEST_URL + "?term=asdf")
            .accept(MediaType.APPLICATION_JSON_VALUE));

        resultActions.andDo(MockMvcResultHandlers.print());
    }

}

Controller:

package my.project;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.List;

@Controller
public class MyController {

    public static final String SUGGEST_URL = "/suggest";

    //http://api.jqueryui.com/autocomplete/#option-source
    @RequestMapping(value = {SUGGEST_URL,}, produces = MediaType.APPLICATION_JSON_VALUE)
    public @ResponseBody
    List<Suggestion> suggest(@RequestParam(name = "term") String term) {

        return Arrays.asList(new Suggestion("label1", "value1"), new Suggestion("label2", "value2"));
    }
}

Config (Thymeleaf omitted for the moment):

package my.project;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@EnableWebMvc
@ComponentScan(basePackages = {"my.project.*",})
@Configuration
@Import(ThymeleafConfig.class)
abstract class TestWebAppConfig extends WebMvcConfigurerAdapter {
}

Error:

    com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException: 406 Not Acceptable for http://localhost/suggest?term=asdf

    at com.gargoylesoftware.htmlunit.WebClient.throwFailingHttpStatusCodeExceptionIfNecessary(WebClient.java:571)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:396)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:304)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:451)
    at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:436)
    at my.project.MyControllerIt.suggestShouldReturnJSON(MyControllerIt.java:
    ...
user2039709
  • 890
  • 7
  • 17

0 Answers0