- 浏览: 399069 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
tyjdzr:
程序已经运行成功,第一次接触webservice,楼主领我入门 ...
java实现webservice实例 -
guosongchao:
楼主介绍的确实简单,但是对于我这种对web service一点 ...
java实现webservice实例 -
gnail_oug:
...
java实现webservice实例 -
safedriver:
楼主真心不错
java实现webservice实例 -
Partys:
Partys 写道addArticleCategories(C ...
RESTful Web Services in Spring 3(上)
相信大家有好多人会使用JUNIT进行单元测试了,但是在WEB开发中仅仅对MVC设计模式中业务逻辑进行测试还是远远不够的,如何对 控制器和视图层进行单元测试将是本文的重点:
主要分享的内容:
一.测试驱动 Java Servlet
二.测试驱动 Spring 控制器
三.用JspTest 测试驱动JSP
开始吧。
一.测试驱动 Java Servlet
servlet通常会有一两个公有方法,每个公有方法处理一种类型的HTTP请求,例如:GET,POST,HEAD,PUT等。每个方法都以doXXX格式命名。大部分情况下都只处理GET和POST请求而已。基类javax.servlet.http.HttpServlet的service方法负责处理所有HTTP请求,其会根据HTTP请求类型把请求转发到对应的doXXX方法上。
doXXX方法的第一个参数HttpServletRequest封装了HTTP请求,其包含请求相关参数,HTTP头及其他信息。
第二个参数HttpServletResponse主要用于给客户端回送应答。任何发给浏览器的HTTP头都可以放到应答对象中。所有想输出的内容都可以转给应答中的printWriter对象和ServletOutputStream对象。
实例:
1.模拟请求和应答
package com.tddinaction.j2ee.web.controller.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class EchoServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter writer = response.getWriter(); for (Enumeration e = request.getParameterNames(); e.hasMoreElements(); ) { String parameter = String.valueOf(e.nextElement()); String[] values = request.getParameterValues(parameter); for (int i = 0; i < values.length; i++) { writer.write(parameter + "=" + values[i]); writer.write("\n"); } } writer.close(); } } package com.tddinaction.j2ee.web.controller.servlet; import junit.framework.TestCase; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; public class EchoServletTest extends TestCase { @Test public void testEchoingParametersWithMultipleValues() throws Exception { //通过第三方的测试替身来模拟请求对象和应答对象。用来模拟浏览器发起的请求 MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); request.addParameter("param1", "param1value1"); request.addParameter("param2", "param2value1"); request.addParameter("param2", "param2value2"); new EchoServlet().doGet(request, response); String[] lines = response.getContentAsString().split("\n"); assertEquals("Expected as many lines as we have parameter values", 3, lines.length); assertEquals("param1=param1value1", lines[0]); assertEquals("param2=param2value1", lines[1]); assertEquals("param2=param2value2", lines[2]); } }
2.测试重定向
package com.tddinaction.j2ee.web.controller.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String user = request.getParameter("j_username"); String pass = request.getParameter("j_password"); if (isValidLogin(user, pass)) { request.getSession().setAttribute("username", user); response.sendRedirect("/frontpage"); } else { forwardTo("/invalidlogin", request, response); } } private boolean isValidLogin(String user, String pass) { if (pass.equals("correctpassword")) { return true; } else if (pass.equals("wrongpassword")) { return false; } return false; } private void forwardTo(String path, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { RequestDispatcher dispatcher = request.getRequestDispatcher(path); dispatcher.forward(request, response); } } package com.tddinaction.j2ee.web.controller.servlet; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; public class TestLoginServlet { private static final String VALID_USERNAME = "validuser"; private LoginServlet servlet; private MockHttpServletRequest request; private MockHttpServletResponse response; @Before public void setUp() { servlet = new LoginServlet(); request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); } @Test public void wrongPasswordShouldRedirectToErrorPage() throws Exception { request.addParameter("j_username", VALID_USERNAME); request.addParameter("j_password", "wrongpassword"); servlet.service(request, response); assertUserEndedUpOnPage("/invalidlogin"); } @Test public void validLoginForwardsToFrontPageAndStoresUsername() throws Exception { request.addParameter("j_username", VALID_USERNAME); request.addParameter("j_password", "correctpassword"); servlet.service(request, response); assertUserEndedUpOnPage("/frontpage"); assertEquals(VALID_USERNAME, request.getSession().getAttribute("username")); } private void assertUserEndedUpOnPage(String expected) { String actual = response.getRedirectedUrl(); if (actual == null) { actual = response.getForwardedUrl(); } assertEquals(expected, actual); } }
二.测试驱动 Spring 控制器
1.失败的登录:
package com.tddinaction.j2ee.web.controller.spring; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import com.tddinaction.j2ee.web.controller.authenticator.Authenticator; public class LoginController implements Controller { private Authenticator authenticator; public void setAuthenticator(Authenticator authenticator) { this.authenticator = authenticator; } public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { String user = request.getParameter("j_username"); String pass = request.getParameter("j_password"); if (authenticator.isValidLogin(user, pass)) { return new ModelAndView("frontpage"); } return new ModelAndView("wrongpassword"); } } package com.tddinaction.j2ee.web.controller.spring; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.web.servlet.ModelAndView; import com.tddinaction.j2ee.web.controller.authenticator.MockAuthenticator; public class TestLoginController { private static final String CORRECT_PASSWORD = "correctpassword"; private static final String VALID_USERNAME = "validuser"; private MockHttpServletRequest request; private MockHttpServletResponse response; private LoginController controller; @Before public void setUp() { request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); controller = new LoginController(); MockAuthenticator auth = new MockAuthenticator(); auth.addUser(VALID_USERNAME, CORRECT_PASSWORD); controller.setAuthenticator(auth); } @Test public void wrongPasswordShouldRedirectToErrorPage() throws Exception { request.addParameter("j_username", "noSuchUsername"); request.addParameter("j_password", "noSuchPassword"); ModelAndView v = controller.handleRequest(request, response); assertEquals("wrongpassword", v.getViewName()); } @Test public void validLoginForwardsToFrontPageAndStoresUsername() throws Exception { request.addParameter("j_username", VALID_USERNAME); request.addParameter("j_password", CORRECT_PASSWORD); ModelAndView v = controller.handleRequest(request, response); assertEquals("frontpage", v.getViewName()); } }
三.用JspTest 测试驱动JSP
JSPTEST是个开源库,他会把JSP编译成SERVLET类然后再执行此SERVLET。详细请登录其官网:
http://sourceforge.net/projects/jsptest/
jsptest里有一个叫做HtmlTestCase的抽象类,所有测试都需要继承这个类。HtmlTestCase提供了一些方法来模拟HTTP请求和渲染JSP文件以及做HTTP相关的验证等
JspTest默认在工程目录下开始寻找JSP文件。
测试FORM表单元素:
package com.tddinaction.j2ee.web.view.jsp.jsptest; import net.sf.jsptest.HtmlTestCase; public class LoginPageTest extends HtmlTestCase { @Override protected String getWebRoot() { return "src/test/resources/websrc/jsp"; } public void testFormFieldsArePresent() throws Exception { get("/login.jsp"); form().shouldHaveField("j_username"); form().shouldHaveField("j_password"); form().shouldHaveField("ddd"); form().shouldHaveSubmitButton("login"); } public void testPreviousUsernameIsRetained() throws Exception { setRequestAttribute("j_username", "bob"); get("/login.jsp"); form().field("j_username").shouldHaveValue("bob"); } }
//login.jsp <%@ page language="Java" %> <html> <body> <form> <% String username = (String) request.getAttribute("j_username"); if (username == null) username = ""; %> <input type="text" name="j_username" value="<%= username %>"/> <input type="password" name="j_password" /> <input type="submit" name="ddd" value="login" /> </form> </body> </html>
发表评论
-
spring框架下配置lucene
2012-02-21 15:34 8621最近这的是投入不少精力在lucene身上,学到一点心得,留此文 ... -
Task Scheduling Simplifications in Spring 3.0
2011-05-19 14:47 2611简单说下基本配置: applicationContex ... -
安装ActiveMQ
2011-04-18 10:28 1229安装activeMQ前先升级jdk到6U24 cd /App ... -
ECLIPSE远程DEBUG
2011-04-18 10:07 1460在服务器上添加监听端 ... -
apache的commons-net实现FTP上传,下载文件
2011-04-15 11:25 2722不多说,上代码: package com.book.s ... -
利用GeneratedKeyHolder获得新建数据主键值
2010-12-24 14:37 7157有时候我们向DB新插入一条数据,都需要获取对应的主键值。在采用 ... -
dbunit解决XML数据中必须表首行有相应字段问题
2010-11-30 09:51 1726DbUnit设计理念: 熟悉单 ... -
jMock Cookbook 中文版
2010-04-29 10:06 2063他娘的,中文版啊!爽,坚决分享! 这里不多介绍JMOC ... -
linux下配置JDK,tomcat
2010-02-26 15:34 1033转自:http://blog.csdn.net/strivem ... -
hsqldb
2010-02-25 00:02 1265import java.sql.Connection; im ... -
RESTful Web Services in Spring 3(下)
2010-02-23 13:44 5645上一篇我主要发了RESTful Web Services in ... -
RESTful Web Services in Spring 3(上)
2010-02-23 10:19 11309通过本文,我将介绍REST的特点,基本设计原则及其简单讲解,最 ... -
spring3实现MVC的rest
2010-02-07 15:21 8516首先配置WEB.XML: <?xml versi ... -
使用 Spring 2.5 基于注解驱动的 Spring MVC
2010-02-07 13:09 890来自地址:https://www.ibm. ... -
log4j配置
2010-01-28 14:07 1149<!-- logging begin--> ... -
java中org.apache.commons.digester类用法
2010-01-28 10:52 1510xml文件内容: <?xml version=& ... -
lucene的索引建立及查找
2010-01-27 11:03 1036package lucene; import org.a ... -
java实现webservice实例
2010-01-25 18:48 131830今天下午突然想研究下WEBSERVICE,从网上找了好多实例, ... -
Hibernate批量插入的方法
2010-01-22 14:46 1503Session session = sessionFact ... -
编写你的第一个Hibernate程序
2010-01-20 11:51 1212注:转载http://www.nit-pro.org/jszl ...
相关推荐
《Python Web开发:测试驱动方法》是一本面向Web开发者的实践指南,作者Harry J.W. Percival通过这本书引导读者掌握使用Python进行测试驱动开发(Test-Driven Development, TDD)的方法。书中内容涵盖了从基础到高级...
**标题解析:** "node-tdd:使用Node和TDD启动测试驱动开发应用程序" 这个标题表明我们将探讨如何利用Node.js环境以及测试驱动开发(Test-Driven Development, TDD)的方法来创建一个应用程序。Node.js是基于Chrome ...
在这个“angular-tdd:用角度进行测试驱动的开发”的主题中,我们将深入探讨如何在Angular项目中实施TDD,以及如何利用JavaScript进行有效的测试。 首先,让我们了解什么是Angular。Angular是由Google维护的一个开源...
对于Java开发者来说,TDD的应用还需要掌握相关工具和库,如Junit、Mockito用于单元测试,Selenium或Appium进行Web或移动应用的端到端测试,以及FitNesse或Cucumber进行验收测试。书中可能还会涵盖如何在IDE(如...
标题中的“关于测试和TDD”指的是Test-Driven Development(测试驱动开发)这一软件开发实践。测试驱动开发是一种敏捷开发方法论,强调在编写实际功能代码之前先编写测试用例。这种方式有助于确保软件质量,降低错误...
Test Drive是一个自以为是,但与框架无关的工具,匹配器和帮助器的集合,用于高效地进行Web应用程序,GUI和客户端组件的“测试驱动开发”。 基于现有的开源项目以及原始的贡献和想法,它不仅提供实用且有效的解决...
【标题】"测试驱动的Docker + Django项目"是基于TestDriven.io提供的教程,旨在指导开发者如何使用TDD(测试驱动开发)方法构建一个结合Docker的Django Web应用程序。这个教程涵盖了Python语言、Django框架以及...
- **Web组件的测试驱动开发**:讨论如何为Java Web应用中的组件编写单元测试和集成测试。 - **数据访问的测试驱动开发**:探讨如何使用TDD来开发数据访问层,包括数据库交互的测试。 - **处理不可预测行为的测试驱动...
"bootcamp-tdd" 是一个训练项目,旨在向参与 BootCamp 的学员介绍如何使用版本控制系统 Git,并引导他们入门测试驱动开发(TDD)的方法。TDD 是一种软件开发实践,强调先编写测试用例,再编写满足这些测试的代码,...
1.3 开发模式:TDD(测试驱动开发)和BDD(行为驱动开发) - TDD:先编写测试用例,再编写实现代码,确保代码满足需求。 - BDD:关注用户行为,通过定义可执行的规格来驱动开发。 【单元测试(Unit Testing)】 ...
TDD(测试驱动开发)和BDD(行为驱动开发)等实践提倡在开发过程中编写测试,确保改动不会引入新的错误。 在压缩包“极品时刻表”中,可能包含了一个示例的ASP.NET Web应用程序或测试用例,用于演示上述测试方法的...
此外,书中还会介绍如何进行测试驱动开发(TDD),使用JUnit和Mockito等工具进行单元测试,以及如何进行集成测试和性能测试,确保代码的质量和系统的稳定性。 最后,对于Java Web系统的持续集成和持续部署(CI/CD)...
测试驱动开发(Test-Driven Development, TDD)是一种软件开发实践,它强调在编写实际代码之前先编写测试。这种做法可以提高代码质量、减少错误并促进更好的设计。"testdrivenio" 指的可能是一个关于 TDD 的教程或...
一、测试驱动开发(TDD)概述 1.1 TDD的核心原则:红-绿-重构 TDD遵循"红-绿-重构"的循环模式。首先,编写一个失败的测试用例(红色),然后编写刚好使该测试通过的最小量的代码(绿色),最后对新代码进行重构,以...
3. 测试驱动开发(TDD):编写单元测试确保组件的正确性。 4. 版本控制:使用Git等工具管理代码版本,便于协同开发和回溯。 5. 文档记录:清晰的组件文档有助于理解和使用。 六、AE组件式开发的挑战 虽然组件化开发...
测试驱动开发 (TDD) - **Visual Studio 支持**:提供了 TDD 的支持。 - **Web 测试**:支持 Web 应用的测试。 ### 13. 单元测试工具 - **NTime/AQTime**:性能测试工具。 - **VS 提供的工具**:包括性能分析和...
9. 测试驱动开发(TDD)与行为驱动开发(BDD): TDD强调先编写测试再实现代码,BDD则关注从用户行为角度定义测试,两者都鼓励自动化测试的早期引入。 10. 自动化测试挑战: - 初始投资:自动化测试工具和框架的学习...