8
  1. I was trying to write unit test for Servlet using sprint-test using mock object

  2. my maven dependency is:

    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-test</artifactId>
       <version>4.0.3.RELEASE</version>
    </dependency>
    

I want to test just java servlet like below following book PRACTICAL TDD AND ACCEPTANCE TDD FOR JAVA DEVELOPER :

package sample;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
    private boolean isValid;

    /**
     * 
     */
    private static final long serialVersionUID = 2473252741884321641L;

    @Override
    public void init() throws ServletException {
        super.init();

    }

    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        String user = req.getParameter("j_username");
        String pass = req.getParameter("j_password");
        if (isValidLogin(user, pass)) {
            resp.sendRedirect("/frontpage");
            req.getSession().setAttribute("username", user);
        } else {
            resp.sendRedirect("/invalidlogin");
        }

    }

    private boolean isValidLogin(String user, String pass) {
        return isValid;
    }

    public void setValid(boolean isValid) {
        this.isValid = isValid;
    }

}

My code is:

    package sample;
    import static org.junit.Assert.assertEquals;
    import org.junit.Test;
    import org.springframework.mock.web.MockHttpServletRequest;
    import org.springframework.mock.web.MockHttpServletResponse;

    public class SprintTestProb {

    @Test
    public void wrongPasswordShouldRedirectToErrorPage() throws Exception {
        MockHttpServletRequest request = new MockHttpServletRequest();
        MockHttpServletResponse response = new MockHttpServletResponse();
        request.addParameter("j_username", "gyanu");
        request.addParameter("j_password", "wrongpassword");
        LoginServlet login = new LoginServlet();
        login.setValid(false);
        login.doPost(request, response);
        assertEquals("/invalidlogin", response.getRedirectedUrl());
    }

}

I got error on line MockHttpServletResponse response = new MockHttpServletResponse(); as follows:

java.lang.ExceptionInInitializerError
    at org.springframework.mock.web.MockHttpServletResponse.<init>(MockHttpServletResponse.java:76)
    at sample.SprintTestProb.wrongPasswordShouldRedirectToErrorPage(SprintTestProb.java:14)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.util.MissingResourceException: Can't find bundle for base name javax.servlet.LocalStrings, locale en_US
    at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)
    at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)
    at java.util.ResourceBundle.getBundle(ResourceBundle.java:721)
    at javax.servlet.ServletOutputStream.<clinit>(ServletOutputStream.java:87)
    ... 25 more
4
  • Tested the code, just like you provided it above, but it works for me, no errors. Commented Apr 30, 2014 at 11:35
  • can you post your pom configuration Commented Apr 30, 2014 at 11:56
  • 2
    In pom: junit 4.7, javax.servlet-api 3.0.1, spring-test 4.0.3, spring-context 4.0.3 Commented Apr 30, 2014 at 12:27
  • 2
    my mistake was using javaee-api solved with using javax.servlet-api. Thank you very much. Commented Apr 30, 2014 at 13:30

3 Answers 3

10

I need to replace dependency for javaee-api with javax.selvlet-api as below:

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
</dependency>
Sign up to request clarification or add additional context in comments.

3 Comments

So I had the same problem, except I had the j2ee-api 7 listed as a dependency (provided). I thought this included the servlet api, but as soon as I added the servlet api as above + provided it resolved my issue. Why on earth did that work?
seems like j2ee-api contains only j2ee-api than can be used for compile. It doesn't contain method bodies so it is not usable for run or deployment. for more mkyong.com/maven/how-to-download-j2ee-api-javaee-jar-from-maven
Right - and it was my understanding that the servlet-api was simply a sub-set of the larger j2ee-api. Are you saying that this is not the case?
1

According to the Spring Framework Reference for Testing you should be using annotations to autowire your mocks. The example in the spring reference:

`

    @WebAppConfiguration
    @ContextConfiguration
    public class WacTests {

    @Autowired WebApplicationContext wac; // cached

    @Autowired MockServletContext servletContext; // cached

    @Autowired MockHttpSession session;

    @Autowired MockHttpServletRequest request;

    @Autowired MockHttpServletResponse response;

    @Autowired ServletWebRequest webRequest;

    //...
}

`

A different example (without annotations) can be found here

Comments

0

I had a similar issue and solved it by adding this dependency to my pom and there is no need to change your javaee-api to javax.servlet

<dependency>
 <groupId>org.mortbay.jetty</groupId>
 <artifactId>servlet-api-2.5</artifactId>
 <version>6.1.11</version>
</dependency>

1 Comment

In java we can find many library implementation according to server we work on and in your case you are using jetty implementation. You can also check for glassfish, tomcat and also more.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.