14

How can we unit test a servlet with an embedded Jetty server?

For example, how to test the servlet method below?

protected void doGet(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    //any logic inside
}
blue123
  • 2,937
  • 7
  • 27
  • 29

2 Answers2

16

I vastly prefer testing servlets with an embedded instance of jetty using something like junit to bootstrap it.

http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/examples/embedded/src/main/java/org/eclipse/jetty/embedded/MinimalServlets.java

that is the minimal example of how to do it.

This is also how we test the vast majority of jetty itself, starting it up and running it through its paces.

For a specific servlet or handler we often use the jetty-client or a SimpleRequest in our jetty-test-helper artifact. A URLConnection works as well.

http://git.eclipse.org/c/jetty/org.eclipse.jetty.toolchain.git/tree/jetty-test-helper/src/main/java/org/eclipse/jetty/toolchain/test/SimpleRequest.java

Here is a test in the jetty-client, it is for jetty-9 so if you want 7 or 8 then look under the corresponding tag, it was refactored quite a bit in jetty-9.

http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTest.java

Note: I recommend you pass 0 as the port for jetty to start up with and that will give you an random open port which you can then pull out of jetty for testing purposes, this avoids the situation where multiple builds are running on CI or parallel builds where there might be a port conflict.

jesse mcconnell
  • 7,102
  • 1
  • 22
  • 33
  • 1
    That's very helpful. But in your example, it doesn't really show how we test the HelloServlet (or something more complicated) by making a request to the servlet. Would you please provide some more info? – blue123 Jan 06 '13 at 14:30
3

You don't need Jetty to test the servlet, you need a unit testing framework, such as JUnit, Mockito, JMock, etc.

Generally speaking, you don't want to use a servlet container when you do unit testing because you want to focus your test on the actual method being tested, having jetty in the way means that you're also testing jetty behavior. After you've done all your unit tests you can move on to integration tests and system tests, and that part can involve external systems such as jetty (using automation frameworks such as Selenium.)

I use Mockito and PowerMock to do my unit testing, you can check out this code for a working example of a real online service (which you can find here). I wrote a tutorial about this service and what it contains, this can be found here.

[Added after getting downvotes from time to time on this answer]: And at the risk of getting even more downvotes, all you downvoters need to read the definition of UNIT TESTING before you click the -1 button. You just don't know what you're talking about.

TheZuck
  • 3,513
  • 2
  • 29
  • 36
  • Thanks a lot for your answer. But what if I want to make the unit test more like an integration test with the help of Jetty? How can I test then? – blue123 Jan 06 '13 at 08:16
  • 8
    Disagree with the above answer, its better to test how your servlet behaves while sitting in a JEE container, as that is how it will run in real life. Better to know how your code will work in real life than in a mocked up object. – Jay Feb 10 '14 at 22:20
  • 6
    I support this answer, the question specifically mentions 'unit-test'. If OP wants to run integration tests, then the title is wrong. – maksimov Feb 13 '14 at 13:21
  • This approach does not work to create an environment that tests client code that actually opens a network connection -- mocks don't create servers, this hugely complicating testing of code that assume a network connection. – user48956 Aug 12 '14 at 20:14
  • 3
    You are correct in your statement that it does not support network connections, but if you read the comments you will understand that we are talking about unit testing not integration tests. In fact, when unit testing javascript (or other client code), you fake network connections in order to prevent network issues from impacting your test results. You do not want a unit test to fail (which infers a code problem) because someone unplugged the network cord... – TheZuck Aug 14 '14 at 07:43
  • PowerMock is fine if code coverage is not important. PowerMock completely messes up code coverage. – GreenSaguaro Feb 09 '18 at 23:47