Как протестировать мой сервлет с помощью JUnit


112

Я создал веб-систему с использованием сервлетов Java и теперь хочу провести тестирование JUnit. My 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"));
    }
}

Таким образом, как обеспечить установку «Cache-Control» при ответе?
Маркус Шульте

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

@aaronvargas: Спасибо за ответ! Но когда я выполняю ваш код, я получаю следующую ошибку: java.util.MissingResourceException: не удается найти пакет для базового имени javax.servlet.LocalStrings, locale de_DE - это происходит во время выполнения new MyServlet (). DoPost ( ...). Есть идеи, что можно сломать?
Бенни Нойгебауэр

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 больше не поддерживается.

Вот еще одна альтернатива, используя библиотеку OpenBrace ObMimic тестовых двойников Servlet 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 сервлетов Javadoc и собственному методу getContentType HttpServletResponse, а также фактическому заголовку Content-Type, созданному, например, Glassfish 3. Вы можете не осознавать этого, если используете обычные фиктивные объекты и ваши собственные ожидания от поведения API. В этом случае это, вероятно, не имеет значения, но в более сложных случаях это своего рода непредвиденное поведение API, которое может стать чем-то вроде издевательства над макетами!

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

  • В этом примере содержимое ответа проверяется как символьные данные (при этом используется кодировка Writer). Мы также могли бы проверить, что использовался Writer ответа, а не его OutputStream (using response.getMimicState().isWritingCharacterContent()), но я понял , что нас интересует только конечный результат, и нам все равно, какие вызовы API его создали (хотя это может быть тоже проверил ...). Также возможно получить содержимое тела ответа в виде байтов, изучить подробное состояние Writer / OutputStream и т. Д.

Полная информация об ObMimic и бесплатная загрузка на сайте OpenBrace . Или вы можете связаться со мной, если у вас возникнут вопросы (контактные данные на сайте).


2

РЕДАКТИРОВАТЬ : Cactus теперь мертвый проект: http://attic.apache.org/projects/jakarta-cactus.html


Вы можете посмотреть на кактус.

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

Описание Проекта

Cactus - это простая тестовая среда для модульного тестирования серверного Java-кода (сервлеты, EJB, библиотеки тегов, фильтры и т. Д.).

Цель Cactus - снизить стоимость написания тестов для серверного кода. Он использует JUnit и расширяет его.

Cactus реализует внутриконтейнерную стратегию, то есть тесты выполняются внутри контейнера.


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. Spring использует контексты для поиска введенных элементов. Если ваш сервлет в конечном итоге использует spring, вы можете предоставить ему тот же контекст, что и тест, добавив следующее к указанному выше методу (перед запуском вызова): XmlWebApplicationContext wctx = new XmlWebApplicationContext (); wctx.setParent (вашAppContext); 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, чтобы получить экземпляр. (См. Видео Guice, где можно найти хорошее введение в DI.) Если вам говорят начать все модульное тестирование, то DI просто необходим.

После внедрения ваших зависимостей вы можете тестировать свой класс изолированно.

Чтобы протестировать сервлет, есть другие старые потоки, которые обсуждали это ... попробуйте здесь и здесь .


Хорошо, спасибо за комментарии, вы говорите, что DataManager должен быть создан в рамках метода внутри этого сервлета? Я смотрел это видео и толком не понял его :( Очень новичок в java и никогда не проводил никаких тестов.
Лунар,

Взгляните на это видео Guice (по крайней мере, начало) - оно хорошо объясняет, почему вы никогда не хотите создавать экземпляр нового объекта в классе, который вы планируете проводить модульное тестирование.
Рой Трулав,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.