2011-03-25 47 views
91

我已经使用Java Servlets创建了一个Web系统,现在想要进行JUnit测试。我的dataManager只是提交给数据库的一段基本代码。你将如何用JUnit测试一个Servlet?如何使用JUnit测试我的servlet

我的代码示例,它允许用户注册/注册,这是从我的主要页面通过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); 
    } 
} 

回答

140

可以使用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")); 
    } 
+0

这样,您如何确保在响应中设置“缓存控制”? – 2013-08-16 09:02:08

+30

您可以使用StringWriter(作为PrintWriter的构造函数的参数)而不是打印到磁盘上的实际文件。然后你会assertTrue(stringWriter.toString()。contains(“My Expected String”));这样,测试将读取/写入内存而不是磁盘。 – spg 2013-09-09 19:06:30

+0

@aaronvargas:谢谢你的回答!但是,当我执行你的代码,然后我得到以下错误:java.util.MissingResourceException:找不到基本名称javax.servlet.LocalStrings,locale de_DE的包 - 它发生在执行新的MyServlet()。doPost ...)。任何想法可能被破坏? – 2014-09-14 15:38:29

0

首先,你或许应该重构这个有点使不创建DataManager的doPost代码..你应该尝试依赖注入来获得一个实例。 (请参阅Guice视频,了解DI的简介。)。如果您被告知开始单元测试,那么DI是必备的。

一旦你的依赖项被注入,你可以单独测试你的类。

要真正测试servlet,还有其他较早的线程已经讨论过这个问题。试试herehere

+0

好,谢谢您的意见,你说的应该DataManager的方法内内创建那个servlet? 我看过那个视频,并没有真正理解它:( 对Java很新,并且从未做过任何类型的测试 – Lunar 2011-03-25 16:23:58

+0

看看那个Guice视频(至少是开头) - 它很好地解释了为什么 – 2011-04-06 14:39:49

0

对于基于web的单元测试,使用Selenium。有一个名为Selenium IDE的Firefox插件,它可以在网页上记录操作并将其导出到JUnit测试用例,它使用Selenium RC来运行测试服务器。

+0

感谢您的看起来不错,但它并没有真正测试方法/ servlet代码,不直接?或者我错了。 – Lunar 2011-03-25 16:23:19

+0

它的确如此, – BalusC 2011-03-25 16:25:53

2

编辑:仙人掌现在是一个死的项目:http://attic.apache.org/projects/jakarta-cactus.html


你可能想看看仙人掌。

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

Project Description

Cactus is a simple test framework for unit testing server-side java code (Servlets, EJBs, Tag Libs, Filters, ...).

The intent of Cactus is to lower the cost of writing tests for server-side code. It uses JUnit and extends it.

Cactus implements an in-container strategy, meaning that tests are executed inside the container.

37

首先,在实际应用中,你永远不会得到一个servlet数据库连接信息;你可以在你的应用服务器上配置它。

但是,有些方法可以测试Servlet而不需要运行容器。一个是使用模拟对象。 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 
    } 
} 
+0

完美的感谢,这一行是不需要的,我忘了删除! “//加载数据库驱动程序 Class.forName(”com.mysql.jdbc.Driver“); ” – Lunar 2011-03-31 15:39:48

+3

@Paul Croarkin:这是一个例子!!非常有帮助 – dionysus 2013-06-12 20:56:14

+0

@Lunar你可以编辑你原来的问题,并删除那里的线(好吧,我已经晚了五年......)。 – 2016-03-31 12:00:45

2

我觉得硒测试更有用于集成或功能(端到端)测试。我正在尝试使用组织。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)); 
     } 

    } 

我希望这可以帮助。

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

} 

} 
+5

对这段代码的解释会有帮助 – 2012-10-03 15:59:34

3

更新于2018年2月:OpenBrace Limited has closed down,其ObMimic产品不再受支持。

下面是另一种替代方法,使用OpenBrace的ObMimic Servlet API test-doubles库(披露:我是它的开发者)。

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” 对象。这提供了Servlet API方法与模拟器内部状态的配置和检查之间的明显区别。

  • 您可能会惊讶于Content-Type的检查包含“charset = ISO-8859-1”。然而,对于给定的“doPost”代码,这是根据Servlet API Javadoc,以及HttpServletResponse自己的getContentType方法,以及在例如所生成的实际内容类型头中生成的。 Glassfish 3.如果使用普通的模拟对象和你自己对API行为的期望,你可能不会意识到这一点。在这种情况下,它可能没有关系,但在更复杂的情况下,这是一种无法预料的API行为,可能会对mock产生一些嘲弄!

  • 我用response.getMimicState().getContentType()作为检查内容类型和说明上述点的最简单的方法,但你确实可以检查“text/html的”关于自己的,如果你想(使用response.getMimicState().getContentTypeMimeType())。检查Content-Type标题的方式与Cache-Control标题相同。

  • 对于这个例子,响应内容被检查为字符数据(使用Writer的编码)。我们还可以检查是否使用了响应的Writer而不是OutputStream(使用response.getMimicState().isWritingCharacterContent()),但我认为我们只关心结果输出,并不在意API调用产生了什么(尽管可能会也要检查...)。它也可以检索响应的主体内容字节,检查作家的详细状态/ OutputStream的等

有ObMimic的全部细节,并在OpenBrace网站上免费下载。或者如果您有任何问题,可以联系我(联系方式在网站上)。

0

只是柜面上述答案不再的Mockito的较新版本的工作,而不是使用mock()when() Mockito.mock()Mockito.when()应使用

1

另一种方法是创建一个嵌入式服务器设置为“主机”您servlet,允许你使用库来调用实际服务器来编写调用(这种方法的实用性有点取决于你如何轻松地对服务器进行“合法的”编程调用) - 我正在测试一个JMS(Java消息传递服务)接入点,客户比比皆是)。

有几条不同的路线你可以去 - 通常两个是tomcat和码头。

警告:选择要嵌入的服务器时需要注意的一点是您正在使用的servlet-api版本(提供类似HttpServletRequest的库)。如果你使用2.5,我发现Jetty 6.x工作良好(这是我将在下面给出的例子)。如果你使用的是servlet-api 3.0,tomcat-7嵌入的东西似乎是一个不错的选择,但是我不得不放弃使用它的尝试,因为我测试的应用程序使用了servlet-api 2.5。尝试混合这两者会导致NoSuchMethod和其他此类异常,当尝试配置或启动服务器时。

您可以设置这样那样的服务器(码头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(); 
} 
+0

另外,如果您选择调查依赖注入,您可能会遇到Spring。 Spring使用上下文来查找注入的项目。如果您的servlet最终使用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 2014-10-28 18:47:16