[转发]测试驱动开发之模拟目标(概念篇)

一、前言

在测试驱动开发进度中大家最关注的是之类一些情节:
目的专一的测试:理想状态下各样测试只有一条断言;
相互独立的测试:对于每个测试都设有预设环境(Fixture)的创制和清除,以便让测试可以以自由顺序执行;
运转速度的测试:你想可以频仍地运行那一个测试。


上目的自然导致一种神秘的顶牛。因为简短而全身心的测试就象征你将会有过多这么的测试,从而确保每个都卓越简便而全身心。而要想使那么些测试相互独立,显然就
须要针对每个测试都有卫生的预设环境。其余,下边大家最终一个对象即是:希望测试速度执行疾速……尽可能地快……以便大家一定频仍地实施
它们(因为我们明日在做测试编程,而照旧有史以来目的--最后的对象编程)。
对此中小型目的的话,以上预设环境的建立就像小难点;可是,在付出大型项目时,即便测试的预设环境变得至极复杂而且结构或解除起来极度狼狈时,大家该怎么做呢?

对上述难题,有些开发人士可能想到创造大气的预设环境代码,而有点开发人员所在的办事环境也许是一种大型的、复杂的系列--那种条件可能是数据库、工作流
系统或者是某种你正在为其开发扩大模块的体系。为此,你的预设环境代码需求使系统进入某种特定的景况,以便根据测试所须要的办法展开响应,那种工作不大可
能很快就到位。
假设存在上述难以处理的测试资源的话,我们如何在专一性、独立性和进程那个目标之间举办衡量呢?

实践评释:模拟目的(即Mocks)是一种极其有效可相信的缓解方案。当大家很难或不容许为某种难以处理的资源成立须要的动静或访问那种资源面临限制时,就足以丰盛发挥模拟目的的效益。其实,模拟目的还有其它紧要功效。在本篇中,大家将详细探索怎样是仿照目的及其可能表述的有关职能。

1.首先用C#葡京赌场网址,打造WebService。源码如下

二、什么是模仿目的(Mocks)

据悉测试驱动开发权威人士的解说,模拟目的(即Mocks)用来替代真实对象的地点,用于测试一些与实际对象举办交互可依靠于真实对象的功力。模拟目的(即Mocks)背后的主导思想是创造轻量级的、可决定的靶子来顶替为了编制测试而急需运用的目的。别的,模拟目的(即Mocks)仍是可以让您指定和测试你的代码与模拟目的(即Mocks)本身之间的竞相。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

三、模拟目的的用途统计

而外能够保险测试预设环境的轻量级,以便可以火速地创设和清除外,使用模拟目标还有别的一些便宜。大家使用模拟目标的因由卓殊之多。具体说来,有以下居多说辞需要大家利用模拟目标的助手缓解方案:

namespace Soap
{
    [WebService(Namespace = “http://Fantasy/WebServiceDemo/")\]
    [System.Web.Services.Protocols.SoapRpcService]
    public class Service : System.Web.Services.WebService
    {
        public Service()
        {

(1)有助于保持设计的松耦合性

选拔模拟目的有助于我们深化以接口为基本的布置性。针对模拟目标举行编程可以清除看重对象内部贯彻的可能性。

        }

(2)检查你的代码应用另一个对象是还是不是适宜

通过在模仿目的中设定期望值(Expectation),大家可以表明编写的代码是或不是恰当地使用了仿照的接口。

        [WebMethod]

(3)由内而异乡利用测试来驱动代码的付出

经过在模仿目的中设定重临值,可以为我们正在开发的代码提供一定的新闻,然后测试最终的一言一动是或不是科学。

        public int AddNumbers(int NumberOne, int NumberTwo)
        {

(4)可以让测试运行得更快

通过模拟诸如通讯或数据库这样的子系统,大家可以防止设置和清除连接等资源所带来的支出。

            return NumberOne + NumberTwo;

(5)可以让大家更易于地开发与硬件配备、远程系统以及其余部分不便处理的资源进行交互的代码

即使我们所编纂的代码须要与局部麻烦处理的资源开展交互的话,那么大家得以创设一个代理层来隔断实际的资源。这样,大家就可以使用代理层的效仿目的,无需访问实际的配备或连串就足以支付代码。

        }
       
    }
}

(6)推迟必需的类达成

本着那几个并未编写出来的而是大家正在开发的代码而又要求与之进行相互的类来说,大家可以利用它们的一成不变目的。那样,大家就可见延缓完成这一个类,以便集中精
力处理那么些类与大家正在编纂的代码之间的接口。从而,大家得以本着实际落成作出决定,直到大家询问了越来越多的音信之后再作决定。借使您的测试所要求的只是模
拟作为,那么使用模拟目的就足足了。

2.因为黑白托管的vc,所以必要拔取微软的soapsdk3.0
 1.先安装soapsdk3.0
下载地址:(http://download.microsoft.com/download/2/e/0/2e068a11-9ef7-45f5-820f-89573d7c4939/soapsdk.exe)
 2.然后创设一个ConsoleAlicaton程序

(7)可以让大家在进展测试驱动开发时把要开发的预制构件与系统的任何部分分隔开来

通过模拟大家正在编辑的代码必须求与之并行的预制构件,大家可以独自专注于这一个部件的支付。那样来说,大家的支出进程就会更快,因为我们正在开发的预制构件与其他部件之间的错综复杂的并行完全处于大家的控制之下。

#include “stdafx.h”
#include <stdio.h>
#include <stdlib.h>

(8)提倡基于接口的设计

留神,当你利用以接口为主(或指引思想)的编程理念时才便于使用模拟目的。

//先导入msxml4.dll,再导入mssoap30.dll
#import “msxml4.dll” 
#import “C:\Program Files\Common Files\MSSoap\Binaries\mssoap30.dll” \
    exclude(“IStream”, “IErrorInfo”, “ISequentialStream”, “_LARGE_INTEGER”, \
    “_ULARGE_INTEGER”, “tagSTATSTG”, “_FILETIME”)
using namespace MSXML2;
using namespace MSSOAPLib30; 

(9)鼓励施用组合而不是一连进行程序设计

在OOP设计思想潜移默化下,半数以上人总会过分地接纳持续技术。结果是,基于继承层次而营造出一种一体化的法力。一个类永远是它所继承的那种样子。于是导致:
模拟位于继承层次中的类的其他一个下面都变得一定忙绿,因为这些类还要承载它所继承的具有的负担。那种想要对特定地点(例如持久性存储)实施模拟的意思使
咱们帮助于编写出相对较小的类,这个类经过与其余类的互相合作而可以落到实处增加的功力。那项目标两样完成,蕴涵模拟目标在内,都能够很简单地相互替换。

void Add2(int No1,int No2)

(10)革新接口

应用你说到底需求贯彻的类的模拟,可以让你早日地有空子考虑接口并改良之。那在采取测试优先的设计时越发如此。你不得不从将要采取那个接口的类的角度来设想这么些接口--因为您从头编制的是一个利用那个接口的实际的测试程序。

{
    //char *_itoa( int value, char *string, int radix );

(11)用来测试非同平日的、不大可能出现的例外情况

您可以创设一个效仿目的,让它回到在平时景况下不会回去的再次回到值,或是创设一个方可在急需的时候抛出相当的模仿目的。那样可以让您很不难地对尤其处理举办测试。显而易见,出现测试的目标,你一点一滴可以编写出一个可以模拟任何不便发生的动静下模拟。

    char str1[10],str2[10];

四、常用模拟框架简介

最初阶,Mock
Object是全然由测试者自己手工撰写的。那样,无可防止的会带来编写测试用例效用低下和测试用例编写困难的流弊,甚至可能会影响XP实践者“测试先行”的心理。此时,各样各种协理创造Mock
Object的工具就涌出了。
此时此刻,在Java阵营中重点的Mock测试工具有JMock,MockCreator,MockRunner,EasyMock,MockMaker等,在微软的.Net阵营中举足轻重是NMock,.NetMock,Rhino
Mocks和Moq等。

    itoa(No1,str1,10); itoa(No2,str2,10);

(1)MockObjects

我们可以动用各个艺术来行使MockObjects编写测试用例:
   
1、基于MockObjects的框架编写自己的Mock
Object已毕并与其别人分享;
    2、直接运用MockObjects提供的Mock
Object举办测试;
   
3、使用其中蕴涵的DynaMock模块快速取得Mock Object实例;
   
4、通过它提供的Helpers对象帮忙大家飞快构建测试环境。

    ISoapSerializerPtr Serializer;

(2)MockMaker

主页为http://*mockmaker*.sourceforge.net/。目前这个框架似乎发展缓慢,这从它针对的应用平台为Windows
2000, Linux, Java 1.2 & Java 1.4那或多或少方可看得出。

    ISoapReaderPtr Reader;

(3)MockCreator

JAVA平台的效仿对话框架,开源网址为http://mockcreator.sourceforge.net/,最新[下载](http://space.itpub.net/14518332/viewspace-430102)支持为MockCreator-2006-09-07。

    ISoapConnectorPtr Connector;    

(4)EasyMock 

手动的协会 Mock
对象会给开发人士带来极度的编码量,而且这一个为开创 Mock
对象而编辑的代码很有可能引入错误。近期,有许多开源项目对动态打造 Mock
对象提供了帮衬,这一个系列可以依照现有的接口或类动态变化,那样不仅能幸免额外的编码工作,同时也暴跌了引入错误的可能。

EasyMock
是一套用于通过简单的办法对于给定的接口生成 Mock
对象的类库。它提供对接口的效仿,可以由此录制、重放、检查三步来已毕大体的测试进度,可以印证措施的调用种类、次数、顺序,可以令
Mock 对象回来指定的值或抛出指定尤其。通过 EasyMock,大家得以方便的组织Mock 对象从而使单元测试顺遂举办。

    // Connect to the service.

(5)NMock 

NMock 是一个按照动态代理的模拟工具,用于
C#
开发。NMock使用了代办方式,那允许类达成一个接口并以代理的不二法门将其他对象的调用转向。NMock生成的模拟是透过在运作时行使动态代理来落到实处的,
那允许模拟目的动态的定义,并不要求添加其它附加的类。寻常,一个效仿的兑现基于被信赖的接口而成立;NMock协理对接口和类的衣冠优孟,其它它还帮助属性
模拟。

    Connector.CreateInstance(__uuidof(HttpConnector30));   

(6)Rhino Mocks和Moq

Rhino
Mocks和Moq是.NET平台下的多少个新创造的精彩的效仿目的框架,有关于此双方的自查自纠,读者可以参照中文博客“正如Moq和Rhino
Mocks七个测试框架
”,URL为:http://blog.joycode.com/haacked/archive/2008/03/24/115023.aspx。从许多的博客文章中可以看到,这两个框架在.NET平台下得到了广泛应用,颇受好评。

    Connector->Property[“EndPointURL”] = “http://localhost:3542/Service.asmx“;   
    Connector->Connect();

(7)JMock

JMock利用模拟目的考虑来对Java代码举行测试。概括来看,JMock具有以下特点:简单扩张,让你火速简单地定义模拟目的,因此不用打破程序间的关系,让你定义灵活的逾越对象之间交互成效而带来测试局限,减少你测试地脆弱性。

字数所限,在此仅仅列举上边三种常见的效仿目的框架,而且只是作了简易介绍。至于种种框架的求实特征与相应示例展示,请参考各框架的官方网站。

    // Begin the message.

    五、小结

从简单的篇章介绍,可以见到模拟目的真正可以扶助大家落到实处在本文起先所关怀的七个对象,即:目的专一的测试;相互独立的测试和高效的测试。到如今甘休,模拟目标依然是一种非凡年轻的定义,有关的新工具和新技巧将遍地被支付出来。针对.NET
2.0框架的Moq就是例证之一。

牢记:个别情状下,可能还必要经过手工格局开创模拟类(那些也许要用到MockObjects那样的框架)。就算如此,你还能通过动用像本文所付出的一步一趋框架那样的工具来成立模拟类的框架代码--你可以依照它们所发生的框架代码进一步增加定制的一举一动。

末段还要记住:模拟目的是一种测试驱动开发的非常好的技能,因为微微意况下它其实不行有用,不过并非过度施用或过度依靠于它。它独自是软件开发中锦囊中的妙计之一,具体的运用则实在环境而定。

初稿链接:http://space.itpub.net/14518332/viewspace-430102

    Connector->Property[“SoapAction”] = “http://Fantasy/WebServiceDemo/Sub“;

    Connector->BeginMessage();      

    // Create the SoapSerializer object.

    Serializer.CreateInstance(__uuidof(SoapSerializer30));

    // Connect the serializer object to the input stream of the connector object.

    Serializer->Init(_variant_t((IUnknown*)Connector->InputStream));

    // Build the SOAP Message.

    Serializer->StartEnvelope(“”,””,””);

    //那里可以拉长SoapHeader验证代码:

    /*

    Serializer->StartHeader(“”);

    Serializer->StartHeaderElement(“MyHeader”,”http://Fantasy/WebServiceDemo/",0,"","NONE“,””);   

    Serializer->StartElement(“UserName”,””,””,””);//填充参数2则失误。

    Serializer->WriteString(_bstr_t(userName));

    */

    Serializer->StartBody(“”);   

    //Serializer->StartElement(“AddNumbers”,”http://Fantasy/WebServiceDemo/“,””,””);
    Serializer->StartElement(“Sub”,”http://Fantasy/WebServiceDemo/“,””,””);

    //(第多个参数可有可无,若加上第四个参数出错!?)

    Serializer->StartElement(“NumberOne”,””,””,””);// NumberOne=

    Serializer->WriteString((_bstr_t)str1);

    Serializer->EndElement();      

    Serializer->StartElement(“NumberTwo”,””,””,””);// NumberOne= 

    Serializer->WriteString((_bstr_t)str2);

    Serializer->EndElement();

    Serializer->EndElement();  

    //

    Serializer->EndBody();

    Serializer->EndEnvelope();

    // Send the message to the XML Web service.   

    Connector->EndMessage();   

    // Read the response. 

    Reader.CreateInstance(__uuidof(SoapReader30));    

    // Connect the reader to the output stream of the connector object.  

    Reader->Load(_variant_t((IUnknown*)Connector->OutputStream), “”);    

    // Display the result.

    printf(“Answer = %s\n”, (const char*)Reader->RpcResult->text);  

}

int main()

{   

    CoInitialize(NULL);   

    Add2(12,24);  

    CoUninitialize();

    return 0;

}

到此一个c++ 访问WebService的demo做完了。
参考网址:http://www.cnblogs.com/arui/archive/2006/06/15/426615.html
http://kimiya25.spaces.live.com/blog/cns!27A083D4FD9435E9!1852.entry?wa=wsignin1.0&sa=490902856
http://wpf-study.googlecode.com/files/VCInvokeWSDLDemo.rar