Як перевірити мій сервлет за допомогою JUnit


112

Я створив веб-систему за допомогою сервлетів Java і тепер хочу зробити тестування JUnit. МояdataManager - лише базовий фрагмент коду, який подає його в базу даних. Як би ви протестували сервлет з JUnit?

Мій приклад коду, який дозволяє користувачеві зареєструватися / зареєструватися, який надсилається з моєї головної сторінки через AJAX:

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);
    }  
}

Відповіді:


169

Ви можете зробити це за допомогою Mockito, щоб макет повернув правильні параметри, переконався, що вони дійсно викликалися (необов'язково вказати кількість разів), написати "результат" та переконатися, що він правильний.

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"));
    }
}

Таким чином, як ви страхуєте "кеш-контроль", встановлений у відповідь?
Маркус Шульте

34
Замість друку до фактичного файлу на диску ви можете використовувати StringWriter (як параметр конструктору PrintWriter). Потім ви будете assertTrue (stringWriter.toString (). Містить ("Мій очікуваний рядок")); Таким чином, тест буде читати / записувати пам'ять замість диска.
спг

@aaronvargas: Дякую за відповідь! Але коли я виконую ваш код, то я отримую таку помилку: java.util.MissingResourceException: Не вдається знайти пакет для базового імені javax.servlet.LocalStrings, locale de_DE - Це відбувається під час виконання нового MyServlet (). DoPost ( ...). Будь-яка ідея, що можна зламати?
Benny Neugebauer

1
@BennyNeugebauer, це здається, що в'язка не на уроці. Я б написав ще один тест JUnit, який лише отримує значення з групи, щоб вирішити проблему.
aaronvargas

@aaronvargas, дякую за відгук! Я знайшов для цього рішення. Мені довелося "javax.servlet-api" до моїх залежностей в моєму pom.xml.
Бенні Нойгебауер

49

По-перше, у реальній програмі ви ніколи не отримаєте інформацію про з'єднання бази даних у сервлеті; ви налаштували б його на своєму сервері додатків.

Однак є способи тестування сервлетів без запуску контейнера. Перший - використовувати макетні об’єкти. Spring пропонує набір дуже корисних макетів для таких речей, як HttpServletRequest, HttpServletResponse, HttpServletSession тощо:

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

Використовуючи ці глузування, ви можете перевірити такі речі

Що станеться, якщо ім'я користувача не вказано в запиті?

Що станеться, якщо ім'я користувача у запиті?

тощо

Потім ви можете робити такі речі, як:

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
    }
}

3

Я вважаю тести Selenium більш корисними при інтеграції або функціональному (від кінця до кінця) тестуванні. Я працюю зі спробою використовувати org.springframework.mock.web , але я не дуже далеко. Я приєдную контролер зразка за допомогою jMock тестовим набором .

По-перше, контролер:

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;
            }
        }
    }

}

Далі тест:

    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));
        }

    }

Я сподіваюся, що це може допомогти.


3

Оновлено лютий 2018 року: OpenBrace Limited закрився , і його продукт ObMimic більше не підтримується.

Ось ще одна альтернатива - використання бібліотеки ObMimic OpenBrace тестових подвійних пакетів API сервлетів (розкриття: я її розробник).

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());

    }

}

Примітки:

  • Кожен "мімік" має об'єкт "mimicState" для свого логічного стану. Це забезпечує чітке розмежування методів API сервлета та конфігурацію та перевірку внутрішнього стану міміки.

  • Ви можете бути здивовані, що перевірка Content-Type включає "charset = ISO-8859-1". Однак для даного коду "doPost" це відповідно до API Servlet Javadoc, власного методу getContentType і HttpServletResponse, а також власного заголовка типу вмісту, створеного, наприклад, Glassfish 3. Ви можете цього не усвідомлювати, якщо використовуєте звичайні макетні об'єкти та власні очікування поведінки API. У цьому випадку це, мабуть, не має значення, але в більш складних випадках це така непередбачувана поведінка API, яка може трохи знущатися з глузувань!

  • Я використовував response.getMimicState().getContentType()як найпростіший спосіб перевірити Content-Type і проілюструвати вищезазначений пункт, але ви дійсно можете перевірити "text / html" самостійно, якщо хочете (використовуєте response.getMimicState().getContentTypeMimeType()). Перевірка заголовка Content-Type так само, як і для заголовка Cache-Control, також працює.

  • У цьому прикладі вміст відповіді перевіряється як символьні дані (для цього використовується кодування Writer). Ми також могли перевірити, чи використовувався Writer відповіді, а не його OutputStream (використовуючи response.getMimicState().isWritingCharacterContent()), але я вважаю, що ми стосуємося лише отриманого результату, і не байдуже, які дзвінки API викликали його (хоча це може бути перевірено теж ...). Також можливо отримати вміст тіла відповіді у вигляді байтів, вивчити докладний стан програми Writer / OutputStream тощо.

Повна інформація про ObMimic та безкоштовне завантаження на веб-сайті OpenBrace . Або ви можете зв’язатися зі мною, якщо у вас виникнуть запитання (контактні дані - на веб-сайті).


2

EDIT : Кактус зараз мертвий проект: http://attic.apache.org/projects/jakarta-cactus.html


Можливо, ви захочете подивитися на кактус.

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

Опис проекту

Кактус - це проста тестова основа для тестування одиничного коду Java на стороні сервера (сервлети, EJB, теги Libs, фільтри, ...).

Метою Кактуса є зниження вартості написання тестів для коду на стороні сервера. Він використовує JUnit і розширює його.

Кактус реалізує стратегію в контейнері, тобто тести виконуються всередині контейнера.


2

Іншим підходом було б створити вбудований сервер для "розміщення" вашого сервлета, дозволяючи писати дзвінки проти нього за допомогою бібліотек, призначених для здійснення дзвінків на фактичні сервери (корисність цього підходу дещо залежить від того, наскільки легко ви можете зробити "законний" програмний дзвінки на сервер - я тестував точку доступу JMS (Java Messaging Service), для якої клієнти мають багато).

Ви можете проїхати пару різних маршрутів - звичайні два - це томат і пристань.

Попередження: що слід пам’ятати, вибираючи сервер для вбудовування, - це версія servlet-api, яку ви використовуєте (бібліотека, яка забезпечує такі класи, як HttpServletRequest). Якщо ви використовуєте 2.5, я виявив, що Jetty 6.x працює добре (про це я наведу нижче). Якщо ви використовуєте servlet-api 3.0, то вбудований матеріал tomcat-7 здається гарним варіантом, однак мені довелося відмовитися від своєї спроби його використовувати, оскільки програма, яку я тестувала, використовувала servlet-api 2.5. Якщо спробувати змішати два, це призведе до використання NoSuchMethod та інших подібних винятків при спробі налаштування або запуску сервера.

Ви можете налаштувати такий сервер, як цей (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();
}

Крім того, якщо ви виберете в дослідженні ін'єкції залежності, ви, ймовірно, наткнетесь на Spring. Весна використовує контексти для пошуку введених елементів. Якщо ваш сервлет закінчується використанням весни, ви можете надати йому той же контекст, що і тест, додавши до описаного вище способу (перед початковим викликом) наступний: 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

Використовуйте Selenium для тестів на веб-основі. Існує плагін Firefox під назвою Selenium IDE, який може записувати дії на веб-сторінці та експортувати до тестових вікон JUnit, який використовує Selenium RC для запуску тестового сервера.


Спасибі за це виглядає добре, але це дійсно не перевіряє методи / код сервлета робить це, а не безпосередньо? чи я помиляюся
Місячний місяць

Це відбувається, запускаючи запити HTTP програмно.
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);

}

}

0

Спочатку вам, мабуть, слід трохи перефактувати це, щоб DataManager не був створений в коді doPost .. Ви повинні спробувати Dependency Injection, щоб отримати екземпляр. (Див. « Гіса» відео для приємного вступу до DI.). Якщо вам говорять про те, щоб почати все тестувати, то DI - це обов'язково.

Після того, як ваші залежності будуть введені, ви можете перевірити свій клас ізольовано.

Щоб насправді протестувати сервлет, є й інші старі теми, які обговорювали це. Спробуйте тут і тут .


Добре дякую за ваші коментарі, ви хочете сказати, що DataManager повинен бути створений в рамках методу в рамках цього сервлета? я дивився це відео і не дуже розумів це :( дуже новий для Java, і ніколи не робив жодного виду тестування.
Місячний

Погляньте на це відео з Guice (принаймні на початку) - це непогано пояснить, чому ви ніколи не хочете інстанціювати новий об’єкт у класі, який ви плануєте на тестуванні одиниць.
Roy Truelove
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.