`
DigitalSonic
  • 浏览: 215101 次
社区版块
存档分类
最新评论

如何简单模拟Web服务

阅读更多

在SOA环境中,系统不可避免地要与其他系统进行交互,可以是基于SOAP的Web服务,基于RESTful Web服务,基于消息队列,甚至是基于RPC远程调用。随着系统依赖的增长,对单个系统进行测试也变得越来越困难,如何有效地隔离各个系统,对系统进行单独的测试呢?

 

本文会给大家介绍一个简单的测试方法——基于Mock进行测试

 

开发过程中常用的测试有单元测试与集成测试,下面也分成两部分来做说明。

当然,你可以选择自己实现一些用于模拟Web服务的类,但本文中的方法选择尽量不要为Mock做过多的开发,因此更多地会选择一些辅助工具来帮助测试。
 

一、单元测试中的Mock

 

单元测试本身就要求将被测试类与它的依赖隔离开来,仅测试被测类本身的逻辑,此时可以选择一些Mock工具对接口进行模拟。是否进行了合理的设计也会影响单元测试的编写,例如,应该遵循“面向接口编程 ”的最佳实践。

 

Java中常用的Mock框架包括:

可以根据个人喜好选择一个合适的框架。本文以jMock为例,进行说明。Web服务的接口定义如下:

 

package mock.sample;

/**
 * 用作范例的接口 
 */
public interface SampleService {
    String operate(String str);
}
 

项目代码Operator类中引用了该服务,需要取得返回值进行后续操作。

package mock.sample;

/**
 * SampleService的调用类 
 */
public class Operator {
    private SampleService sampleService;

    /**
     * 调用sampleService
     * 1、如果返回值result长度小于等于5,返回str+result
     * 2、如果返回值result长度大于5,返回result 
     */
    public String operate(String str) {
        String result = sampleService.operate(str);
        if (result != null && result.length() <= 5) {
            result = str + result;
        }
        return result;
    }

    public void setSampleService(SampleService sampleService) {
        this.sampleService = sampleService;
    }
}
 

在编写单元测试时,为SampleService模拟一个对象注入Operator。关于jMock的使用,请参考jMock的《Getting Started 》或者《Cheat Sheet 》。jMock主要是使用录制-回放 的方式,通过预先设定期望的输入与输出实现Mock。

 

package mock.sample;

import static org.junit.Assert.assertEquals;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JMock.class)
public class OperatorTest {
    private Mockery context = new JUnit4Mockery();

    @Test
    public void testOperate() {
        Operator operator = new Operator();
        final SampleService sampleService = context.mock(SampleService.class);
        operator.setSampleService(sampleService);
        context.checking(new Expectations() {
            {
                oneOf(sampleService).operate("hi");
                will(returnValue("HelloWorld!"));

                oneOf(sampleService).operate("hello");
                will(returnValue("world"));
            }
        });

        assertEquals("HelloWorld!", operator.operate("hi"));
        assertEquals("helloworld", operator.operate("hello"));
    }
}
 

单元测试中直接通过编码的途径用jMock模拟了外部系统的逻辑,业务代码并不关注究竟是调用了真是的Web服务,还是Mock对象。同样的,对于DAO等依赖也可以使用同样的方式进行模拟。

 

二、集成测试中的Mock

 

集成测试时同样可以通过编程的方式实现Mock,比如在Spring上下文中加载Mock的Bean而非通过XFire(或其他Web服务框架)引入的客户端。但这种做法未免过于繁琐,而且在希望改变Mock类返回结果时,可能需要修改代码重新编译发布。更有甚者,上线时如果忘记从测试的配置换回生产配置,就会出大问题。

 

当然,你可以选择部署一台真实的服务提供方,但有时出于种种原因,这并不是一个很好的选择。

 

相信在测试Web服务时,不少人都是用过soapUI ,但仅限于使用soapUI调用Web服务,其实强大的soapUI还可以Mock服务,根据事先的配置(Groovy脚本、XPath匹配、顺序、随机等方法)返回不同的结果。其实现原理简单地说就是根据给定的WSDL模拟Web服务,接受请求后根据配置解析请求,随后返回预先设定的结果,这里的请求和响应都是标准的SOAP报文。

 

简单实现步骤如下:

  1. 创建一个新的soapUI项目,在“New soapUI Project”对话框中输入WSDL地址,随后选中“Create MockService”。
  2. 在“Generate MockService”对话框中选中要模拟的操作,Path和Port尽量和真实的目标服务器保持一致。例如,发布WSDL的路径可能是http://xxx:8080/services/sampleService?wsdl,那么Path就是/services/cardInfoService,Port为8080。
  3. 编辑应答SOAP报文及返回逻辑。

在MockService的各个方法上点右键可以进入MockOperation Editor或者直接创建新的MockResponse。MockService创建时,每个操作都会有个Response,没有设定规则时,这就是默认应答。

 

可以仅使用一个Response,多次调用需要不同结果时手工修改,但这样一点都不“自动化”,可以通过soapUI的分派机制自动根据规则返回对应结果。

 

soapUI支持的分派机制(详见MockOperations and Responses )有:

  • SCRIPT,使用Groovy脚本。
  • SEQUENCE,按照MockResponse添加的顺序逐个返回。
  • QUERY-MATCH,基于请求内容选择合适的结果返回。可以指定XPath路径及该节点的期望值,如果匹配的话返回对应Response。
  • XPATH,与QUERY-MATCH类似,XPath节点的值就是要返回的MockResponse的名字。
  • RAMDOM,随机返回。

个人认为XPATH和QUERY-MATCH这两种分派机制在复杂情况下比较好用,如果再复杂,可以考虑SCRIPT。以XPATH为例,假设请求报文如下:

 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fac="http://sample.mock.SampleService">
   <soapenv:Header/>
   <soapenv:Body>
      <fac:operate>
         <fac:in0>hi</fac:in0>
      </fac:operate>
   </soapenv:Body>
</soapenv:Envelope>

 

可以设置两个MockResponse,名字分别为“hi”和“hello”,在编辑器中选择“XPATH” ,设置如下XPATH:

declare namespace fac='http://sample.mock.SampleService'
//fac:in0

当//fac:in0的值是“hi”时就会返回名为“hi”的MockResponse。“hi”MockResponse内容:

 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fac="http://sample.mock.SampleService">
   <soapenv:Header/>
   <soapenv:Body>
      <fac:operate>
         <fac:out>HelloWorld!</fac:out>
      </fac:operate>
   </soapenv:Body>
</soapenv:Envelope>
 

如果使用QUERY_MATCH,除了填写XPath,还要再填写“Expacted Value”,比如“hi”或者“hello”,然后“Dispatch to”中选择合适的MockResponse。

 

在项目中只需要把Web服务的Endpoint地址做成可配置的,就可以方便地调整测试与生产环境的Endpoint,实现Mock与真实服务器的切换。

 

使用Mock可以大大降低测试的成本,工欲善其事必先利其器,选择一个合适的Mock工具,可以帮助你更好的进行测试。So,行动吧~

 

 

 

分享到:
评论

相关推荐

    web服务器模拟

    【Web服务器模拟】 ...在“web服务器模拟”这个主题中,我们将深入探讨Web服务器的工作原理、常见类型以及如何通过模拟来...通过学习和实践,我们可以更深入地理解Web服务在互联网中的重要作用,并提升自己的技术能力。

    C++ window 模拟web服务

    本项目“C++ window 模拟web服务”旨在利用C++在Windows环境下构建一个简易的Web服务器,它能够处理HTTP协议中的GET和POST请求,并能解析JSON格式的数据。下面我们将详细探讨相关的知识点。 1. **C++**:作为面向...

    Serversocker 模拟web服务器tomcat

    简单的使用ServerSocket模拟下,Tomcatweb服务器。

    C#建立最简单的Web服务,无需IIS

    当我们谈论“C#建立最简单的Web服务,无需IIS”时,实际上是在讨论如何利用C#创建自托管的Web服务,这种服务不需要依赖于Internet Information Services (IIS)这样的传统Web服务器。IIS通常用于托管ASP.NET应用,但...

    JAVA模拟web服务器

    java ServerSocket 实现的简单web服务器 参考http://blog.csdn.net/hzaccp3/article/details/12589651

    web服务的建立和引用——模拟网上购物

    这个项目“web服务的建立和引用——模拟网上购物”旨在通过实例演示如何构建和使用Web服务来模拟一个简单的网上购物系统。在这个过程中,我们将重点讨论ASP.NET Web服务的使用,这是一种由微软提供的强大工具,用于...

    web模拟登陆网站源码

    总的来说,这个源码可能演示了如何在C#环境下创建一个简单的桌面应用,该应用能模拟登录Web站点,并处理登录过程中涉及的各种交互和认证细节。对于学习网络编程、Web自动化测试和数据抓取的开发者来说,这是一个有...

    TCP简单模拟webservices

    ### TCP简单模拟Webservices:理解完成端口与Webservice的工作原理 #### 一、完成端口(IOCP):Windows平台下的高效IO模型 **完成端口**(Input/Output Completion Ports,简称IOCP)是Windows平台下设计用于处理...

    简单模拟IIS服务器程序

    IIS是一个强大的Web服务应用程序平台,可以用来发布网页、管理网络服务、处理客户端请求并返回响应。 【模拟IIS服务器程序】 模拟IIS服务器程序是为了帮助开发者理解和学习IIS的工作原理而创建的。这类程序通常会...

    WebApi搭建简单服务器demo亲测可用

    WebApi搭建简单服务器是一个常见的开发任务,特别是在构建RESTful API服务时。本示例通过C#语言和Visual Studio(VS)环境,为我们提供了一个快速入门的解决方案。在本文中,我们将深入探讨如何利用这些工具创建一个...

    WPF+SelfHost+HttpClient 模拟web通信

    在本文中,我们将深入探讨如何在WPF应用中利用SelfHost和HttpClient来模拟Web通信,同时结合Mvvmlight框架,实现一个简单的客户端-服务器通信示例。首先,让我们逐个解析这些关键技术点。 1. **WPF (Windows ...

    jetty简单启动web服务

    本文将详细介绍如何使用Jetty快速启动一个简单的Web服务,并进行微服务和简单桩测试。 首先,我们需要了解Jetty的基本概念。Jetty是一个开源项目,它的核心功能是解析HTTP协议并处理Web请求。由于其小巧且无需额外...

    使用DELPHI开发,调用WEB服务例子

    Web服务通常基于SOAP(简单对象访问协议)或REST(Representational State Transfer)架构,使用XML作为数据交换格式。在DELPHI中,我们可以利用内置的HTTP客户端组件(如TIdHTTP)和XML处理组件(如TXMLDocument)...

    Web服务响应模拟Mockaccino.zip

    Mockaccino 是一个简单 Node(和 Express.js) 服务器,可以快速模拟 Web 服务响应。示例代码:{  ...  "queryStringParam": "tc",  "mockResponses": {  "default": {  "/test1": {  /* behaviour...

    开启并请求web服务

    Java作为一种广泛使用的编程语言,提供了丰富的库和框架来实现Web服务的开发和消费。本篇文章将深入探讨如何在Java环境中开启并请求Web服务。 一、Web服务类型 1. SOAP(Simple Object Access Protocol):基于XML...

    web 服务和调用,对ecplise 的用法

    5. **Eclipse插件**:为了更好地开发和测试Web服务,Eclipse有多个插件可用,例如,Web Tools Platform (WTP) 提供了对Web服务开发的支持,包括生成WSDL、部署服务和模拟客户端调用。 6. **调试和测试**:在Eclipse...

    (完整word版)F5负载均衡WEB服务器模拟.doc

    F5负载均衡WEB服务器模拟 在本文档中,我们将介绍F5负载均衡WEB服务器模拟的安装、配置和使用过程。F5负载均衡器是一种高性能的负载均衡解决方案,能够满足大规模Web应用程序的需求。本文档将分步骤地指导读者完成...

    基于UIP的简单WEB服务器

    【基于UIP的简单WEB服务器】是一个项目,它在Visual Studio 2005(VS2005)开发环境中,利用UIP(User Interface Protocol)的API接口...对于想要学习嵌入式Web服务或者UIP协议的开发者来说,这是一个很好的实践案例。

    构建XML Web服务:基于Microsoft NET平台

    10. **调试与测试**:Visual Studio提供了强大的Web服务调试工具,可以在开发环境中模拟调用并查看返回结果。此外,可以使用SOAP UI等第三方工具进行独立的Web服务测试。 综上所述,构建基于Microsoft .NET平台的...

Global site tag (gtag.js) - Google Analytics