Cách kiểm tra servlet của tôi bằng JUnit


112

Tôi đã tạo một hệ thống web bằng Java Servlet và bây giờ muốn thực hiện thử nghiệm JUnit. Của tôi dataManagerchỉ là một đoạn mã cơ bản gửi nó vào cơ sở dữ liệu. Bạn sẽ kiểm tra Servlet bằng JUnit như thế nào?

Ví dụ mã của tôi cho phép người dùng đăng ký / đăng ký, được gửi từ trang chính của tôi qua 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);
    }  
}

Câu trả lời:


169

Bạn có thể thực hiện việc này bằng cách sử dụng Mockito để mô hình trả về các tham số chính xác, xác minh rằng chúng thực sự được gọi (tùy chọn chỉ định số lần), viết 'kết quả' và xác minh nó đúng.

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

Bằng cách này, làm thế nào để bạn đảm bảo "Kiểm soát bộ nhớ cache" được đặt khi phản hồi?
Markus Schulte

34
Thay vì in ra tệp thực trên đĩa, bạn có thể sử dụng StringWriter (làm tham số cho hàm tạo của PrintWriter). Sau đó, bạn sẽ khẳng địnhTrue (stringWriter.toString (). Chứa ("Chuỗi mong đợi của tôi")); Bằng cách này, bài kiểm tra sẽ đọc / ghi bộ nhớ thay vì đĩa.
spg

@aaronvargas: Cảm ơn câu trả lời của bạn! Nhưng khi tôi thực thi mã của bạn, thì tôi gặp lỗi sau: java.util.MissingResourceException: Không tìm thấy gói cho tên cơ sở javax.servlet.LocalStrings, locale de_DE - Nó xảy ra trong quá trình thực thi MyServlet mới (). DoPost ( ...). Bất kỳ ý tưởng những gì có thể bị phá vỡ?
Benny Neugebauer

1
@BennyNeugebauer, có vẻ như gói không có trên classpath. Tôi sẽ viết một bài kiểm tra JUnit khác Chỉ nhận một giá trị từ Gói để cô lập vấn đề.
aaronvargas

@aaronvargas, cảm ơn bạn đã phản hồi! Tôi đã tìm thấy một giải pháp cho nó. Tôi đã phải "javax.servlet-api" cho các phần phụ thuộc của tôi trong pom.xml của tôi.
Benny Neugebauer

49

Trước hết, trong một ứng dụng thực, bạn sẽ không bao giờ nhận được thông tin kết nối cơ sở dữ liệu trong một servlet; bạn sẽ định cấu hình nó trong máy chủ ứng dụng của mình.

Tuy nhiên, có nhiều cách để kiểm tra Servlet mà không cần chạy một vùng chứa. Một là sử dụng các đối tượng giả. Spring cung cấp một bộ mock rất hữu ích cho những thứ như HttpServletRequest, HttpServletResponse, HttpServletSession, v.v.:

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

Sử dụng những mô phỏng này, bạn có thể kiểm tra những thứ như

Điều gì xảy ra nếu tên người dùng không có trong yêu cầu?

Điều gì xảy ra nếu tên người dùng có trong yêu cầu?

Vân vân

Sau đó, bạn có thể làm những thứ như:

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

Tôi thấy các bài kiểm tra Selenium hữu ích hơn với kiểm tra tích hợp hoặc chức năng (end-to-end). Tôi đang cố gắng sử dụng org.springframework.mock.web , nhưng tôi không tiến xa lắm. Tôi đang đính kèm bộ điều khiển mẫu với bộ thử nghiệm jMock .

Đầu tiên, Bộ điều khiển:

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

}

Tiếp theo, bài kiểm tra:

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

    }

Tôi hy vọng điều này có thể giúp ích.


3

Cập nhật tháng 2 năm 2018: OpenBrace Limited đã đóng cửa và sản phẩm ObMimic của nó không còn được hỗ trợ.

Đây là một giải pháp thay thế khác, sử dụng thư viện ObMimic của OpenBrace về bản thử nghiệm API Servlet (tiết lộ: Tôi là nhà phát triển của nó).

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

    }

}

Ghi chú:

  • Mỗi "bắt chước" có một đối tượng "mimicState" cho trạng thái logic của nó. Điều này cung cấp sự phân biệt rõ ràng giữa các phương thức API Servlet và cấu hình và kiểm tra trạng thái bên trong của mô hình bắt chước.

  • Bạn có thể ngạc nhiên khi kiểm tra Loại-Nội dung bao gồm "charset = ISO-8859-1". Tuy nhiên, đối với mã "doPost" đã cho, đây là theo Servlet API Javadoc và phương thức getContentType của riêng HttpServletResponse và tiêu đề Content-Type thực tế được tạo trên ví dụ như Glassfish 3. Bạn có thể không nhận ra điều này nếu sử dụng các đối tượng giả bình thường và kỳ vọng của riêng mình về hành vi của API. Trong trường hợp này có lẽ không thành vấn đề, nhưng trong những trường hợp phức tạp hơn thì đây là loại hành vi API không lường trước được có thể tạo ra một chút chế giễu!

  • Tôi đã sử dụng response.getMimicState().getContentType() như một cách đơn giản nhất để kiểm tra Content-Type và minh họa điểm trên, nhưng bạn thực sự có thể tự kiểm tra "text / html" nếu bạn muốn (sử dụng response.getMimicState().getContentTypeMimeType()). Kiểm tra tiêu đề Content-Type giống như cách kiểm tra tiêu đề Cache-Control cũng hoạt động.

  • Đối với ví dụ này, nội dung phản hồi được kiểm tra dưới dạng dữ liệu ký tự (với điều này bằng cách sử dụng mã hóa của Writer). Chúng tôi cũng có thể kiểm tra xem Writer của phản hồi đã được sử dụng chứ không phải là Dòng ra của nó (sử dụngresponse.getMimicState().isWritingCharacterContent() ), nhưng tôi đã hiểu rằng chúng tôi chỉ quan tâm đến kết quả đầu ra và không quan tâm những gì các lệnh gọi API tạo ra nó (mặc dù điều đó có thể đã kiểm tra quá ...). Cũng có thể truy xuất nội dung phần thân của phản hồi dưới dạng byte, kiểm tra trạng thái chi tiết của Writer / OutputStream, v.v.

Có đầy đủ chi tiết về ObMimic và tải xuống miễn phí tại trang web OpenBrace . Hoặc bạn có thể liên hệ với tôi nếu bạn có bất kỳ câu hỏi nào (chi tiết liên hệ có trên website).


2

CHỈNH SỬA : Cactus hiện là một dự án đã chết: http://attic.apache.org/projects/jakarta-cactus.html


Bạn có thể muốn nhìn vào cây xương rồng.

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

mô tả dự án

Cactus là một khung thử nghiệm đơn giản để kiểm tra đơn vị mã java phía máy chủ (Servlets, EJBs, Tag Libs, Filters, ...).

Mục đích của Cactus là giảm chi phí viết thử nghiệm cho mã phía máy chủ. Nó sử dụng JUnit và mở rộng nó.

Cactus triển khai chiến lược trong vùng chứa, nghĩa là các bài kiểm tra được thực hiện bên trong vùng chứa.


2

Một cách tiếp cận khác sẽ là tạo một máy chủ nhúng để "lưu trữ" servlet của bạn, cho phép bạn viết các lệnh gọi chống lại nó với các thư viện dùng để thực hiện các cuộc gọi đến các máy chủ thực tế (tính hữu ích của cách tiếp cận này phụ thuộc vào mức độ dễ dàng bạn có thể tạo chương trình "hợp pháp" cuộc gọi đến máy chủ - Tôi đang kiểm tra điểm truy cập JMS (Dịch vụ nhắn tin Java), dành cho rất nhiều máy khách).

Có một số tuyến đường khác nhau mà bạn có thể đi - hai tuyến đường thông thường là tomcat và cầu cảng.

Cảnh báo: điều cần lưu ý khi chọn máy chủ để nhúng là phiên bản của servlet-api bạn đang sử dụng (thư viện cung cấp các lớp như HttpServletRequest). Nếu bạn đang sử dụng 2.5, tôi thấy Jetty 6.x hoạt động tốt (đó là ví dụ tôi sẽ đưa ra bên dưới). Nếu bạn đang sử dụng servlet-api 3.0, nội dung nhúng tomcat-7 có vẻ là một lựa chọn tốt, tuy nhiên tôi đã phải từ bỏ nỗ lực sử dụng nó, vì ứng dụng tôi đang thử nghiệm đã sử dụng servlet-api 2.5. Cố gắng kết hợp cả hai sẽ dẫn đến NoSuchMethod và các ngoại lệ khác như vậy khi cố gắng cấu hình hoặc khởi động máy chủ.

Bạn có thể thiết lập một máy chủ như thế này (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();
}

Ngoài ra, nếu bạn chọn tiêm phụ thuộc điều tra, có thể bạn sẽ gặp phải Spring. Spring sử dụng các ngữ cảnh để tra cứu các mục được đưa vào. Nếu servlet của bạn kết thúc bằng cách sử dụng spring, bạn có thể cung cấp cho nó cùng ngữ cảnh với bài kiểm tra bằng cách thêm phần sau vào phương thức trên (trước khi bắt đầu cuộc gọi): 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

Sử dụng Selenium cho các bài kiểm tra đơn vị dựa trên web. Có một plugin Firefox có tên là Selenium IDE có thể ghi lại các hành động trên trang web và xuất sang các testcase JUnit sử dụng Selenium RC để chạy máy chủ thử nghiệm.


Cảm ơn vì điều này có vẻ tốt, nhưng nó không thực sự kiểm tra các phương thức / mã servlet, không trực tiếp? hoặc là tôi sai.
Ngày

Nó thực hiện, bằng cách kích hoạt các yêu cầu HTTP theo lập trình.
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

Đầu tiên, bạn có thể nên cấu trúc lại điều này một chút để DataManager không được tạo trong mã doPost .. bạn nên thử Dependency Injection để lấy một phiên bản. (Xem Guice video để biết phần giới thiệu thú vị về DI.). Nếu bạn được yêu cầu bắt đầu thử nghiệm mọi thứ, thì DI là điều bắt buộc phải có.

Sau khi các phụ thuộc của bạn được tiêm vào, bạn có thể kiểm tra lớp của mình một cách riêng biệt.

Để thực sự kiểm tra servlet, có những chủ đề cũ khác đã thảo luận về điều này .. hãy thử ở đâyở đây .


Được rồi, cảm ơn bạn đã nhận xét, bạn nói rằng DataManager nên được tạo trong một phương thức bên trong servlet đó? tôi đã xem video đó và không thực sự hiểu nó :( rất mới với java và chưa bao giờ thực hiện bất kỳ loại thử nghiệm nào.
Ngày

Hãy xem video Guice đó (ít nhất là phần đầu) - nó làm rất tốt việc giải thích lý do tại sao bạn không bao giờ muốn khởi tạo một đối tượng mới trong một lớp mà bạn định kiểm tra đơn vị.
Roy Truelove
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.