Cómo probar mi servlet usando JUnit

112

Creé un sistema web usando Java Servlets y ahora quiero hacer pruebas JUnit. MidataManager es solo una pieza básica de código que lo envía a la base de datos. ¿Cómo probarías un Servlet con JUnit?

Mi ejemplo de código que permite a un usuario registrarse / registrarse, que se envía desde mi página principal a través de 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);
    }  
}
Lunar
fuente

Respuestas:

169

Puede hacer esto usando Mockito para que el simulacro devuelva los parámetros correctos, verifique que realmente fueron llamados (opcionalmente especifique el número de veces), escriba el 'resultado' y verifique que sea correcto.

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
fuente
De esta manera, ¿cómo se asegura de que "Cache-Control" se establezca en respuesta?
Markus Schulte
34
En lugar de imprimir en un archivo real en el disco, puede usar un StringWriter (como un parámetro para el constructor de PrintWriter). Luego afirmaríaTrue (stringWriter.toString (). Contains ("Mi cadena esperada")); De esta forma, la prueba leerá / escribirá memoria en lugar de disco.
spg
@aaronvargas: ¡Gracias por tu respuesta! Pero cuando ejecuto su código, aparece el siguiente error: java.util.MissingResourceException: No se puede encontrar el paquete para el nombre base javax.servlet.LocalStrings, locale de_DE - Ocurre durante la ejecución de new MyServlet (). DoPost ( ...). ¿Alguna idea de lo que podría romperse?
Benny Neugebauer
1
@BennyNeugebauer, parece que el paquete no está en el classpath. Escribiría otra prueba JUnit que solo obtenga un valor del paquete para aislar el problema.
Aaronvargas
@aaronvargas, ¡gracias por tus comentarios! Encontré una solución para eso. Tuve que "javax.servlet-api" para mis dependencias en mi pom.xml.
Benny Neugebauer
49

En primer lugar, en una aplicación real, nunca obtendría información de conexión de base de datos en un servlet; lo configuraría en su servidor de aplicaciones.

Sin embargo, hay formas de probar Servlets sin tener un contenedor en ejecución. Uno es usar objetos simulados. Spring proporciona un conjunto de simulaciones muy útiles para cosas como HttpServletRequest, HttpServletResponse, HttpServletSession, etc.

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

Con estos simulacros, puedes probar cosas como

¿Qué sucede si el nombre de usuario no está en la solicitud?

¿Qué sucede si el nombre de usuario está en la solicitud?

etc

Luego podrías hacer cosas como:

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
fuente
3

Encuentro que las pruebas de selenio son más útiles con pruebas de integración o funcionales (de un extremo a otro). Estoy tratando de usar org.springframework.mock.web , pero no estoy muy avanzado . Adjunto un controlador de muestra con un conjunto de pruebas jMock .

Primero, el controlador:

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

}

A continuación, la prueba:

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

    }

Espero que esto ayude.

Steve Gelman
fuente
3

Actualizado en febrero de 2018: OpenBrace Limited ha cerrado y su producto ObMimic ya no es compatible.

Aquí hay otra alternativa, utilizando la biblioteca ObMimic de OpenBrace de pruebas dobles de API de Servlet (divulgación: soy su desarrollador).

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

    }

}

Notas:

  • Cada "mimic" tiene un objeto "mimicState" para su estado lógico. Esto proporciona una clara distinción entre los métodos de API de Servlet y la configuración e inspección del estado interno de la mímica.

  • Es posible que se sorprenda de que la comprobación de Content-Type incluya "charset = ISO-8859-1". Sin embargo, para el código "doPost" dado, esto es según el Javadoc de la API de Servlet, y el método getContentType de HttpServletResponse, y el encabezado Content-Type real producido en, por ejemplo, Glassfish 3. Es posible que no se dé cuenta de esto si usa objetos simulados normales y su propias expectativas del comportamiento de la API. En este caso, probablemente no importe, pero en casos más complejos, este es el tipo de comportamiento de API imprevisto que puede hacer que las burlas se burlen un poco.

  • La he utilizado response.getMimicState().getContentType()como la forma más sencilla de verificar el tipo de contenido e ilustrar el punto anterior, pero de hecho podría verificar "texto / html" por sí solo si quisiera (usar response.getMimicState().getContentTypeMimeType()). También funciona comprobar el encabezado Content-Type de la misma forma que el encabezado Cache-Control.

  • Para este ejemplo, el contenido de la respuesta se verifica como datos de caracteres (con esto usando la codificación del escritor). También podríamos verificar que se usó el Writer de la respuesta en lugar de su OutputStream (usando response.getMimicState().isWritingCharacterContent()), pero he entendido que solo nos preocupa la salida resultante, y no nos importa qué llamadas API lo produjeron (aunque eso podría ser comprobado también ...). También es posible recuperar el contenido del cuerpo de la respuesta como bytes, examinar el estado detallado del Writer / OutputStream, etc.

Hay detalles completos de ObMimic y una descarga gratuita en el sitio web de OpenBrace . O puede contactarme si tiene alguna pregunta (los datos de contacto están en el sitio web).

Mike Kaufman
fuente
2

EDITAR : Cactus es ahora un proyecto muerto: http://attic.apache.org/projects/jakarta-cactus.html


Es posible que desee mirar cactus.

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

Descripción del Proyecto

Cactus es un marco de prueba simple para pruebas unitarias de código java del lado del servidor (Servlets, EJB, Tag Libs, Filters, ...).

La intención de Cactus es reducir el costo de escribir pruebas para el código del lado del servidor. Utiliza JUnit y lo amplía.

Cactus implementa una estrategia en el contenedor, lo que significa que las pruebas se ejecutan dentro del contenedor.

Chris Persichetti
fuente
2

Otro enfoque sería crear un servidor incrustado para "alojar" su servlet, permitiéndole escribir llamadas en él con bibliotecas destinadas a realizar llamadas a servidores reales (la utilidad de este enfoque depende en cierto modo de la facilidad con la que pueda hacer que la programación sea "legítima" llamadas al servidor: estaba probando un punto de acceso JMS (Java Messaging Service), para el cual abundan los clientes).

Hay un par de rutas diferentes a las que puede ir: las dos habituales son tomcat y jetty.

Advertencia: algo a tener en cuenta al elegir el servidor para incrustar es la versión de servlet-api que está utilizando (la biblioteca que proporciona clases como HttpServletRequest). Si está utilizando 2.5, encontré que Jetty 6.x funciona bien (que es el ejemplo que daré a continuación). Si está utilizando servlet-api 3.0, el material integrado de tomcat-7 parece ser una buena opción, sin embargo, tuve que abandonar mi intento de usarlo, ya que la aplicación que estaba probando usaba servlet-api 2.5. Intentar mezclar los dos resultará en NoSuchMethod y otras excepciones similares al intentar configurar o iniciar el servidor.

Puede configurar un servidor como este (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
fuente
Además, si elige investigar la inyección de dependencia, probablemente se encontrará con Spring. Spring usa contextos para buscar elementos inyectados. Si su servlet termina usando Spring, puede proporcionarle el mismo contexto que la prueba agregando lo siguiente al método anterior (antes de la llamada de inicio): 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

Utilice Selenium para pruebas unitarias basadas en la web. Hay un complemento de Firefox llamado Selenium IDE que puede registrar acciones en la página web y exportar a casos de prueba JUnit que usa Selenium RC para ejecutar el servidor de prueba.

BalusC
fuente
Gracias por esto se ve bien, pero realmente no prueba los métodos / código de servlet, ¿no es así directamente? o estoy equivocado.
Lunar
Lo hace, activando solicitudes HTTP mediante programación.
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
fuente
0

Primero, probablemente debería refactorizar esto un poco para que el DataManager no se cree en el código doPost. Debería probar Dependency Injection para obtener una instancia. (Vea el video de Guice para una buena introducción a DI). Si le dicen que comience a probar todo unitario, entonces DI es imprescindible.

Una vez que se inyectan sus dependencias, puede probar su clase de forma aislada.

Para probar el servlet, hay otros subprocesos más antiguos que han discutido esto ... intente aquí y aquí .

Roy Truelove
fuente
Ok, gracias por sus comentarios, ¿está diciendo que el DataManager debería crearse dentro de un método dentro de ese servlet? Vi ese video y realmente no lo entendí :( muy nuevo en Java, y nunca hice ningún tipo de prueba.
Lunar
Eche un vistazo a ese video de Guice (al menos al principio): hace un buen trabajo al explicar por qué nunca desea crear una instancia de un nuevo objeto en una clase en la que planea realizar pruebas unitarias.
Roy Truelove