Pregunta

currently I am working on a spring based application. I do have some unit tests for many purposes of the application. The problem is, I've not found any solution to do a real integration test on my application.

Let me give you an example:

In my current tests I do setup a request for a specific controller and pass those components to my handler:

// setup request
request.setMethod("GET");
request.setRequestURI("/customer");
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", "Basic xyz"); // base_64
handlerAdapter.handle(request, response, myController);

But this is not a real integration test, because what I am saying is, okay I do have a request, and myController should handle this request.

That's a problem, because what I really want to test is the following:

I do have a request, and my application should handle this request. I do not want to specify the controller because in case of a running application and a request to "/customer" spring does dispatch which controller solves my request. I really want to simulate that I am a browser or another client sending requests to my backend.

The reason I want to test this is, that otherwise some kind of tests passes although the tested functionality doesn't work in the "real world"

I could give you this example to understand, in which way the tests differ from the production run:

Let's assume I do have a file upload within a form with a parameter. My controller function is this one:

@RequestMapping(value="/{id}", method = RequestMethod.PUT, headers="content-type=multipart/form-data")
public ResponseEntity<String> createFromMyForm(@PathVariable("id") Long id, @RequestParam String myParameter, @RequestParam MultipartFile myFile) {
//...
}

Have a look at the RequestMethod.PUT, this is not working in an production build, because html standard for uploading files is POST.

In my unit test I am doing this:

// setup request
MockMultipartHttpServletRequest multipartRequest = new MockMultipartHttpServletRequest();
MockHttpServletResponse multipartResponse = new MockHttpServletResponse();

// Open file
final FileInputStream fis = new FileInputStream("img/test.png");
MockMultipartFile multipartFile = new MockMultipartFile(
            "myParameter", fis);

// generate multipart mock
multipartRequest.addFile(multipartFile);
multipartRequest.addParameter("json", "test");

// send request
handlerAdapter.handle(multipartRequest, multipartResponse, controller);

Problem: The test passes, while it should not. The reasons this test passes are several. First I am specifing the request. I do not say I have a request, but instead I have to say I have a MultipartRequest. This leads the dispatcher servlet to return true in an function called something like isMultipartRequest(). In the production run it returns false, because there are no multipart requests on PUT methods. Further I specify again the controller which should handle this request.

Maybe there are other examples, but what I want to say is, is there any way to test my application under real conditions including my html protocol and everything else?

I would really appreciate any kind of help!

Thanks in advance

¿Fue útil?

Solución

Integration tests will test the integration between your code and your framework, but at some point you need to deploy the application and test it for real.

Have a look at HtmlUnit. It's a Junit-based framework for navigating and functionally testing web applications.

Better yet, look at Selenium. This will actually drive a real browser and assert on the contents of the page. It's more complex than HtmlUnit, but generally results in a more meaningful test, especially for javascript-heavy webapps.

Otros consejos

Last week I have found this two spring classes,

I never used them, and I am not 100% sure how they work. But I wanted to point it out, because they are not mentioned in the Spring Reference. And believe me it is a lot of work to get the first real integration test with an deployed server running. So as long as the mocks do not mock the stuff you want to test, I strongly recommend to use the mocks.


But I you really need a deployed application (like skaffman suggested in his answer). Then I want to mention an two other Testing Framwork:

  • Selenium 2.0 / Webdriver - It is a framework to controll the browser, but it has also a HtmlUnit Driver that "simulate" an browser
  • Apache HttpComponents HttpClient. It is more low level then Selenium, but I get it running in 10 minutes, while I need much more time for real Selenium tests.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top