So testen Sie mein Servlet mit JUnit

112

Ich habe ein Websystem mit Java-Servlets erstellt und möchte jetzt JUnit-Tests durchführen. My dataManagerist nur ein grundlegender Code, der ihn an die Datenbank sendet. Wie würden Sie ein Servlet mit JUnit testen?

Mein Codebeispiel, mit dem sich ein Benutzer registrieren / anmelden kann und das von meiner Hauptseite über AJAX gesendet wird:

public void doPost(HttpServletRequest request, HttpServletResponse response) 
         throws ServletException, IOException{

    // Get parameters
    String userName = request.getParameter("username");
    String password = request.getParameter("password");
    String name = request.getParameter("name");

    try {

        // Load the database driver
        Class.forName("com.mysql.jdbc.Driver");

        //pass reg details to datamanager       
        dataManager = new DataManager();
        //store result as string
        String result = dataManager.register(userName, password, name);

        //set response to html + no cache
        response.setContentType("text/html");
        response.setHeader("Cache-Control", "no-cache");
        //send response with register result
        response.getWriter().write(result);

    } catch(Exception e){
        System.out.println("Exception is :" + e);
    }  
}
Mond
quelle

Antworten:

169

Sie können dies mit Mockito tun , damit der Mock die richtigen Parameter zurückgibt, überprüft, ob sie tatsächlich aufgerufen wurden (optional die Anzahl angeben), das 'Ergebnis' schreibt und überprüft, ob es korrekt ist.

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.io.*;
import javax.servlet.http.*;
import org.apache.commons.io.FileUtils;
import org.junit.Test;

public class TestMyServlet extends Mockito{

    @Test
    public void testServlet() throws Exception {
        HttpServletRequest request = mock(HttpServletRequest.class);       
        HttpServletResponse response = mock(HttpServletResponse.class);    

        when(request.getParameter("username")).thenReturn("me");
        when(request.getParameter("password")).thenReturn("secret");

        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        when(response.getWriter()).thenReturn(writer);

        new MyServlet().doPost(request, response);

        verify(request, atLeast(1)).getParameter("username"); // only if you want to verify username was called...
        writer.flush(); // it may not have been flushed yet...
        assertTrue(stringWriter.toString().contains("My expected string"));
    }
}
aaronvargas
quelle
Wie stellen Sie auf diese Weise sicher, dass "Cache-Control" bei der Antwort eingestellt wird?
Markus Schulte
34
Anstatt in eine tatsächliche Datei auf der Festplatte zu drucken, können Sie einen StringWriter verwenden (als Parameter für den Konstruktor von PrintWriter). Sie würden dann assertTrue (stringWriter.toString (). Enthält ("My Expected String")); Auf diese Weise liest / schreibt der Test den Speicher anstelle der Festplatte.
spg
@aaronvargas: Danke für deine Antwort! Wenn ich Ihren Code ausführe, wird folgende Fehlermeldung angezeigt: java.util.MissingResourceException: Bundle für Basisname javax.servlet.LocalStrings, Gebietsschema de_DE nicht gefunden - Dies geschieht während der Ausführung des neuen MyServlet (). DoPost ( ...). Irgendeine Idee, was kaputt gehen könnte?
Benny Neugebauer
1
@BennyNeugebauer, hört sich so an, als ob sich das Bundle nicht auf dem Klassenpfad befindet. Ich würde einen weiteren JUnit-Test schreiben, der nur einen Wert aus dem Bundle erhält, um das Problem zu isolieren.
Aaronvargas
@aaronvargas, danke für dein Feedback! Ich habe eine Lösung dafür gefunden. Ich musste "javax.servlet-api" zu meinen Abhängigkeiten in meiner pom.xml.
Benny Neugebauer
49

Zunächst einmal würden Sie in einer realen Anwendung niemals Datenbankverbindungsinformationen in einem Servlet erhalten. Sie würden es in Ihrem App-Server konfigurieren.

Es gibt jedoch Möglichkeiten, Servlets zu testen, ohne dass ein Container ausgeführt wird. Eine besteht darin, Scheinobjekte zu verwenden. Spring bietet eine Reihe sehr nützlicher Mocks für Dinge wie HttpServletRequest, HttpServletResponse, HttpServletSession usw.:

http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/mock/web/package-summary.html

Mit diesen Mocks können Sie Dinge wie testen

Was passiert, wenn der Benutzername nicht in der Anfrage enthalten ist?

Was passiert, wenn der Benutzername in der Anfrage enthalten ist?

etc

Sie könnten dann Dinge tun wie:

import static org.junit.Assert.assertEquals;

import java.io.IOException;

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

import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;

public class MyServletTest {
    private MyServlet servlet;
    private MockHttpServletRequest request;
    private MockHttpServletResponse response;

    @Before
    public void setUp() {
        servlet = new MyServlet();
        request = new MockHttpServletRequest();
        response = new MockHttpServletResponse();
    }

    @Test
    public void correctUsernameInRequest() throws ServletException, IOException {
        request.addParameter("username", "scott");
        request.addParameter("password", "tiger");

        servlet.doPost(request, response);

        assertEquals("text/html", response.getContentType());

        // ... etc
    }
}
Paul Croarkin
quelle
3

Ich finde Selen-Tests nützlicher bei Integrations- oder Funktionstests (End-to-End-Tests). Ich arbeite mit dem Versuch, org.springframework.mock.web zu verwenden , aber ich bin nicht sehr weit. Ich schließe einen Sample-Controller mit einem jMock an -Testsuite hinzu.

Zunächst der Controller:

package com.company.admin.web;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import com.company.admin.domain.PaymentDetail;
import com.company.admin.service.PaymentSearchService;
import com.company.admin.service.UserRequestAuditTrail;
import com.company.admin.web.form.SearchCriteria;

/**
 * Controls the interactions regarding to the refunds.
 * 
 * @author slgelma
 *
 */
@Controller
@SessionAttributes({"user", "authorization"})
public class SearchTransactionController {

    public static final String SEARCH_TRANSACTION_PAGE = "searchtransaction";

    private PaymentSearchService searchService;
    //private Validator searchCriteriaValidator;
    private UserRequestAuditTrail notifications;

    @Autowired
    public void setSearchService(PaymentSearchService searchService) {
        this.searchService = searchService;
    }

    @Autowired
    public void setNotifications(UserRequestAuditTrail notifications) {
        this.notifications = notifications;
    }

    @RequestMapping(value="/" + SEARCH_TRANSACTION_PAGE)
    public String setUpTransactionSearch(Model model) {
        SearchCriteria searchCriteria = new SearchCriteria();
        model.addAttribute("searchCriteria", searchCriteria);
        notifications.transferTo(SEARCH_TRANSACTION_PAGE);
        return SEARCH_TRANSACTION_PAGE;
    }

    @RequestMapping(value="/" + SEARCH_TRANSACTION_PAGE, method=RequestMethod.POST, params="cancel")
    public String cancelSearch() {
        notifications.redirectTo(HomeController.HOME_PAGE);
        return "redirect:/" + HomeController.HOME_PAGE;
    }

    @RequestMapping(value="/" + SEARCH_TRANSACTION_PAGE, method=RequestMethod.POST, params="execute")
    public String executeSearch(
            @ModelAttribute("searchCriteria") @Valid SearchCriteria searchCriteria,
            BindingResult result, Model model,
            SessionStatus status) {
        //searchCriteriaValidator.validate(criteria, result);
        if (result.hasErrors()) {
            notifications.transferTo(SEARCH_TRANSACTION_PAGE);
            return SEARCH_TRANSACTION_PAGE;
        } else {
            PaymentDetail payment = 
                searchService.getAuthorizationFor(searchCriteria.geteWiseTransactionId());
            if (payment == null) {
                ObjectError error = new ObjectError(
                        "eWiseTransactionId", "Transaction not found");
                result.addError(error);
                model.addAttribute("searchCriteria", searchCriteria);
                notifications.transferTo(SEARCH_TRANSACTION_PAGE);
                return SEARCH_TRANSACTION_PAGE;
            } else {
                model.addAttribute("authorization", payment);
                notifications.redirectTo(PaymentDetailController.PAYMENT_DETAIL_PAGE);
                return "redirect:/" + PaymentDetailController.PAYMENT_DETAIL_PAGE;
            }
        }
    }

}

Als nächstes der Test:

    package test.unit.com.company.admin.web;

    import static org.hamcrest.Matchers.containsString;
    import static org.hamcrest.Matchers.equalTo;
    import static org.junit.Assert.assertThat;

    import org.jmock.Expectations;
    import org.jmock.Mockery;
    import org.jmock.integration.junit4.JMock;
    import org.jmock.integration.junit4.JUnit4Mockery;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.validation.ObjectError;
    import org.springframework.web.bind.support.SessionStatus;

    import com.company.admin.domain.PaymentDetail;
    import com.company.admin.service.PaymentSearchService;
    import com.company.admin.service.UserRequestAuditTrail;
    import com.company.admin.web.HomeController;
    import com.company.admin.web.PaymentDetailController;
    import com.company.admin.web.SearchTransactionController;
    import com.company.admin.web.form.SearchCriteria;

    /**
     * Tests the behavior of the SearchTransactionController.
     * @author slgelma
     *
     */
    @RunWith(JMock.class)
    public class SearchTransactionControllerTest {

        private final Mockery context = new JUnit4Mockery(); 
        private final SearchTransactionController controller = new SearchTransactionController();
        private final PaymentSearchService searchService = context.mock(PaymentSearchService.class);
        private final UserRequestAuditTrail notifications = context.mock(UserRequestAuditTrail.class);
        private final Model model = context.mock(Model.class);


        /**
         * @throws java.lang.Exception
         */
        @Before
        public void setUp() throws Exception {
            controller.setSearchService(searchService);
            controller.setNotifications(notifications);
        }

        @Test
        public void setUpTheSearchForm() {

            final String target = SearchTransactionController.SEARCH_TRANSACTION_PAGE;

            context.checking(new Expectations() {{
                oneOf(model).addAttribute(
                        with(any(String.class)), with(any(Object.class)));
                oneOf(notifications).transferTo(with(any(String.class)));
            }});

            String nextPage = controller.setUpTransactionSearch(model);
            assertThat("Controller is not requesting the correct form", 
                    target, equalTo(nextPage));
        }

        @Test
        public void cancelSearchTest() {

            final String target = HomeController.HOME_PAGE;

            context.checking(new Expectations(){{
                never(model).addAttribute(with(any(String.class)), with(any(Object.class)));
                oneOf(notifications).redirectTo(with(any(String.class)));
            }});

            String nextPage = controller.cancelSearch();
            assertThat("Controller is not requesting the correct form", 
                    nextPage, containsString(target));
        }

        @Test
        public void executeSearchWithNullTransaction() {

            final String target = SearchTransactionController.SEARCH_TRANSACTION_PAGE;

            final SearchCriteria searchCriteria = new SearchCriteria();
            searchCriteria.seteWiseTransactionId(null);

            final BindingResult result = context.mock(BindingResult.class);
            final SessionStatus status = context.mock(SessionStatus.class);

            context.checking(new Expectations() {{
                allowing(result).hasErrors(); will(returnValue(true));
                never(model).addAttribute(with(any(String.class)), with(any(Object.class)));
                never(searchService).getAuthorizationFor(searchCriteria.geteWiseTransactionId());
                oneOf(notifications).transferTo(with(any(String.class)));
            }});

            String nextPage = controller.executeSearch(searchCriteria, result, model, status);
            assertThat("Controller is not requesting the correct form", 
                    target, equalTo(nextPage));
        }

        @Test
        public void executeSearchWithEmptyTransaction() {

            final String target = SearchTransactionController.SEARCH_TRANSACTION_PAGE;

            final SearchCriteria searchCriteria = new SearchCriteria();
            searchCriteria.seteWiseTransactionId("");

            final BindingResult result = context.mock(BindingResult.class);
            final SessionStatus status = context.mock(SessionStatus.class);

            context.checking(new Expectations() {{
                allowing(result).hasErrors(); will(returnValue(true));
                never(model).addAttribute(with(any(String.class)), with(any(Object.class)));
                never(searchService).getAuthorizationFor(searchCriteria.geteWiseTransactionId());
                oneOf(notifications).transferTo(with(any(String.class)));
            }});

            String nextPage = controller.executeSearch(searchCriteria, result, model, status);
            assertThat("Controller is not requesting the correct form", 
                    target, equalTo(nextPage));
        }

        @Test
        public void executeSearchWithTransactionNotFound() {

            final String target = SearchTransactionController.SEARCH_TRANSACTION_PAGE;
            final String badTransactionId = "badboy"; 
            final PaymentDetail transactionNotFound = null;

            final SearchCriteria searchCriteria = new SearchCriteria();
            searchCriteria.seteWiseTransactionId(badTransactionId);

            final BindingResult result = context.mock(BindingResult.class);
            final SessionStatus status = context.mock(SessionStatus.class);

            context.checking(new Expectations() {{
                allowing(result).hasErrors(); will(returnValue(false));
                atLeast(1).of(model).addAttribute(with(any(String.class)), with(any(Object.class)));
                oneOf(searchService).getAuthorizationFor(with(any(String.class)));
                    will(returnValue(transactionNotFound));
                oneOf(result).addError(with(any(ObjectError.class)));
                oneOf(notifications).transferTo(with(any(String.class)));
            }});

            String nextPage = controller.executeSearch(searchCriteria, result, model, status);
            assertThat("Controller is not requesting the correct form", 
                    target, equalTo(nextPage));
        }

        @Test
        public void executeSearchWithTransactionFound() {

            final String target = PaymentDetailController.PAYMENT_DETAIL_PAGE;
            final String goodTransactionId = "100000010";
            final PaymentDetail transactionFound = context.mock(PaymentDetail.class);

            final SearchCriteria searchCriteria = new SearchCriteria();
            searchCriteria.seteWiseTransactionId(goodTransactionId);

            final BindingResult result = context.mock(BindingResult.class);
            final SessionStatus status = context.mock(SessionStatus.class);

            context.checking(new Expectations() {{
                allowing(result).hasErrors(); will(returnValue(false));
                atLeast(1).of(model).addAttribute(with(any(String.class)), with(any(Object.class)));
                oneOf(searchService).getAuthorizationFor(with(any(String.class)));
                    will(returnValue(transactionFound));
                oneOf(notifications).redirectTo(with(any(String.class)));
            }});

            String nextPage = controller.executeSearch(searchCriteria, result, model, status);
            assertThat("Controller is not requesting the correct form", 
                    nextPage, containsString(target));
        }

    }

Ich hoffe das könnte helfen.

Steve Gelman
quelle
3

Aktualisiert im Februar 2018: OpenBrace Limited wurde geschlossen und sein ObMimic-Produkt wird nicht mehr unterstützt.

Hier ist eine weitere Alternative, bei der OpenBraces ObMimic- Bibliothek mit Servlet-API-Test-Doubles verwendet wird (Offenlegung: Ich bin der Entwickler).

package com.openbrace.experiments.examplecode.stackoverflow5434419;

import static org.junit.Assert.*;
import com.openbrace.experiments.examplecode.stackoverflow5434419.YourServlet;
import com.openbrace.obmimic.mimic.servlet.ServletConfigMimic;
import com.openbrace.obmimic.mimic.servlet.http.HttpServletRequestMimic;
import com.openbrace.obmimic.mimic.servlet.http.HttpServletResponseMimic;
import com.openbrace.obmimic.substate.servlet.RequestParameters;
import org.junit.Before;
import org.junit.Test;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Example tests for {@link YourServlet#doPost(HttpServletRequest,
 * HttpServletResponse)}.
 *
 * @author Mike Kaufman, OpenBrace Limited
 */
public class YourServletTest {

    /** The servlet to be tested by this instance's test. */
    private YourServlet servlet;

    /** The "mimic" request to be used in this instance's test. */
    private HttpServletRequestMimic request;

    /** The "mimic" response to be used in this instance's test. */
    private HttpServletResponseMimic response;

    /**
     * Create an initialized servlet and a request and response for this
     * instance's test.
     *
     * @throws ServletException if the servlet's init method throws such an
     *     exception.
     */
    @Before
    public void setUp() throws ServletException {
        /*
         * Note that for the simple servlet and tests involved:
         * - We don't need anything particular in the servlet's ServletConfig.
         * - The ServletContext isn't relevant, so ObMimic can be left to use
         *   its default ServletContext for everything.
         */
        servlet = new YourServlet();
        servlet.init(new ServletConfigMimic());
        request = new HttpServletRequestMimic();
        response = new HttpServletResponseMimic();
    }

    /**
     * Test the doPost method with example argument values.
     *
     * @throws ServletException if the servlet throws such an exception.
     * @throws IOException if the servlet throws such an exception.
     */
    @Test
    public void testYourServletDoPostWithExampleArguments()
            throws ServletException, IOException {

        // Configure the request. In this case, all we need are the three
        // request parameters.
        RequestParameters parameters
            = request.getMimicState().getRequestParameters();
        parameters.set("username", "mike");
        parameters.set("password", "xyz#zyx");
        parameters.set("name", "Mike");

        // Run the "doPost".
        servlet.doPost(request, response);

        // Check the response's Content-Type, Cache-Control header and
        // body content.
        assertEquals("text/html; charset=ISO-8859-1",
            response.getMimicState().getContentType());
        assertArrayEquals(new String[] { "no-cache" },
            response.getMimicState().getHeaders().getValues("Cache-Control"));
        assertEquals("...expected result from dataManager.register...",
            response.getMimicState().getBodyContentAsString());

    }

}

Anmerkungen:

  • Jedes "mimic" hat ein "mimicState" -Objekt für seinen logischen Zustand. Dies bietet eine klare Unterscheidung zwischen den Servlet-API-Methoden und der Konfiguration und Überprüfung des internen Status des Mimics.

  • Sie werden überrascht sein, dass die Prüfung des Inhaltstyps "Zeichensatz = ISO-8859-1" enthält. Für den angegebenen "doPost" -Code entspricht dies jedoch der Servlet-API Javadoc, der getContentType-Methode von HttpServletResponse und dem tatsächlichen Content-Type-Header, der beispielsweise in Glassfish 3 erstellt wurde. Dies ist möglicherweise nicht möglich, wenn Sie normale Scheinobjekte und Ihre verwenden eigene Erwartungen an das Verhalten der API. In diesem Fall spielt es wahrscheinlich keine Rolle, aber in komplexeren Fällen ist dies die Art von unerwartetem API-Verhalten, das Spott ein wenig verspotten kann!

  • Ich habe response.getMimicState().getContentType()als einfachste Methode verwendet, um den Inhaltstyp zu überprüfen und den obigen Punkt zu veranschaulichen, aber Sie könnten tatsächlich selbst nach "text / html" suchen, wenn Sie möchten (mit response.getMimicState().getContentTypeMimeType()). Das Überprüfen des Content-Type-Headers auf die gleiche Weise wie für den Cache-Control-Header funktioniert ebenfalls.

  • In diesem Beispiel wird der Antwortinhalt als Zeichendaten überprüft (wobei die Codierung des Writers verwendet wird). Wir könnten auch überprüfen, ob der Writer der Antwort anstelle des OutputStream (using response.getMimicState().isWritingCharacterContent()) verwendet wurde, aber ich habe angenommen, dass wir uns nur mit der resultierenden Ausgabe befassen und es uns egal ist, welche API-Aufrufe sie erzeugt haben (obwohl dies möglich sein könnte) auch überprüft ...). Es ist auch möglich, den Textinhalt der Antwort als Bytes abzurufen, den detaillierten Status des Writer / OutputStream usw. zu überprüfen.

Es gibt alle Details zu ObMimic und einen kostenlosen Download auf der OpenBrace- Website. Oder Sie können mich kontaktieren, wenn Sie Fragen haben (Kontaktdaten finden Sie auf der Website).

Mike Kaufman
quelle
2

EDIT : Cactus ist jetzt ein totes Projekt: http://attic.apache.org/projects/jakarta-cactus.html


Vielleicht möchten Sie sich Kakteen ansehen.

http://jakarta.apache.org/cactus/

Projektbeschreibung

Cactus ist ein einfaches Testframework zum Testen von serverseitigem Java-Code (Servlets, EJBs, Tag Libs, Filter, ...).

Mit Cactus sollen die Kosten für das Schreiben von Tests für serverseitigen Code gesenkt werden. Es verwendet JUnit und erweitert es.

Cactus implementiert eine In-Container-Strategie, dh, Tests werden im Container ausgeführt.

Chris Persichetti
quelle
2

Ein anderer Ansatz wäre, einen eingebetteten Server zu erstellen, der Ihr Servlet "hostet" und es Ihnen ermöglicht, Aufrufe mit Bibliotheken zu schreiben, die dazu gedacht sind, Aufrufe an tatsächliche Server zu tätigen (der Nutzen dieses Ansatzes hängt etwas davon ab, wie einfach Sie "legitim" programmatisch machen können Anrufe an den Server - Ich habe einen JMS-Zugriffspunkt (Java Messaging Service) getestet, für den es viele Clients gibt.

Es gibt ein paar verschiedene Routen - die üblichen zwei sind Kater und Steg.

Warnung: Bei der Auswahl des einzubettenden Servers ist die von Ihnen verwendete Version der Servlet-API zu beachten (die Bibliothek, die Klassen wie HttpServletRequest bereitstellt). Wenn Sie 2.5 verwenden, hat Jetty 6.x gut funktioniert (das ist das Beispiel, das ich unten geben werde). Wenn Sie Servlet-API 3.0 verwenden, scheint das eingebettete Tomcat-7-Material eine gute Option zu sein. Ich musste jedoch meinen Versuch, es zu verwenden, abbrechen, da die Anwendung, die ich getestet habe, Servlet-API 2.5 verwendet. Der Versuch, beide zu mischen, führt zu NoSuchMethod und anderen solchen Ausnahmen, wenn Sie versuchen, den Server zu konfigurieren oder zu starten.

Sie können einen solchen Server wie folgt einrichten (Jetty 6.1.26, Servlet-API 2.5):

public void startServer(int port, Servlet yourServletInstance){
    Server server = new Server(port);
    Context root = new Context(server, "/", Context.SESSIONS);

    root.addServlet(new ServletHolder(yourServletInstance), "/servlet/context/path");

    //If you need the servlet context for anything, such as spring wiring, you coudl get it like this
    //ServletContext servletContext = root.getServletContext();

    server.start();
}
Romeara
quelle
Wenn Sie sich für die Untersuchung der Abhängigkeitsinjektion entscheiden, werden Sie wahrscheinlich auf Spring stoßen. Spring verwendet Kontexte, um injizierte Elemente zu suchen. Wenn Ihr Servlet Spring verwendet, können Sie ihm denselben Kontext wie dem Test bereitstellen, indem Sie der obigen Methode (vor dem Startaufruf) Folgendes hinzufügen: XmlWebApplicationContext wctx = new XmlWebApplicationContext (); wctx.setParent (yourAppContext); wctx.setConfigLocation (""); wctx.setServletContext (servletContext); wctx.refresh (); servletContext.setAttribute (WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wctx);
Romeara
1

Verwenden Sie Selen für webbasierte Unit-Tests. Es gibt ein Firefox-Plugin namens Selenium IDE, das Aktionen auf der Webseite aufzeichnen und in JUnit-Testfälle exportieren kann, die Selenium RC zum Ausführen des Testservers verwenden .

BalusC
quelle
Danke, das sieht gut aus, aber es testet die Methoden / den Servlet-Code nicht wirklich, nicht direkt? oder liege ich falsch.
Mond
Dies geschieht durch programmgesteuertes Auslösen von HTTP-Anforderungen.
BalusC
1
 public class WishServletTest {
 WishServlet wishServlet;
 HttpServletRequest mockhttpServletRequest;
 HttpServletResponse mockhttpServletResponse;

@Before
public void setUp(){
    wishServlet=new WishServlet();
    mockhttpServletRequest=createNiceMock(HttpServletRequest.class);
    mockhttpServletResponse=createNiceMock(HttpServletResponse.class);
}

@Test
public void testService()throws Exception{
    File file= new File("Sample.txt");
    File.createTempFile("ashok","txt");
    expect(mockhttpServletRequest.getParameter("username")).andReturn("ashok");
    expect(mockhttpServletResponse.getWriter()).andReturn(new PrintWriter(file));
    replay(mockhttpServletRequest);
    replay(mockhttpServletResponse);
    wishServlet.doGet(mockhttpServletRequest, mockhttpServletResponse);
    FileReader fileReader=new FileReader(file);
    int count = 0;
    String str = "";
    while ( (count=fileReader.read())!=-1){
        str=str+(char)count;
    }

    Assert.assertTrue(str.trim().equals("Helloashok"));
    verify(mockhttpServletRequest);
    verify(mockhttpServletResponse);

}

}
Ashok
quelle
0

Zuerst sollten Sie dies wahrscheinlich ein wenig umgestalten, damit der DataManager nicht im doPost-Code erstellt wird. Sie sollten Dependency Injection versuchen, um eine Instanz abzurufen. (Siehe die Guice Eine nette Einführung in DI finden Video.) Wenn Sie aufgefordert werden, mit dem Testen aller Einheiten zu beginnen, ist DI ein Muss.

Sobald Ihre Abhängigkeiten eingefügt sind, können Sie Ihre Klasse isoliert testen.

Um das Servlet tatsächlich zu testen, gibt es andere ältere Threads, die dies besprochen haben. Versuchen Sie es hier und hier .

Roy Truelove
quelle
Ok, danke für Ihre Kommentare. Wollen Sie damit sagen, dass der DataManager innerhalb einer Methode in diesem Servlet erstellt werden soll? Ich habe dieses Video gesehen und es nicht wirklich verstanden :( Sehr neu in Java, und habe noch nie irgendwelche Tests durchgeführt.
Lunar
Schauen Sie sich dieses Guice-Video an (zumindest am Anfang) - es erklärt gut, warum Sie niemals ein neues Objekt in einer Klasse instanziieren möchten, die Sie für Unit-Tests planen.
Roy Truelove