RhinoMock入门(7)——Do,With和Record-playback

简介: (一)Do(delegate) 有时候在测试过程中只返回一个静态的值是不够的,在这种情况下,Do()方法可以用来在方法调用时添加自定义的行为。一般来说,Do()方法会替换方法调用。它的返回值会从模拟的调用中返回(即使是有异常发生也是这样)。

(一)Do(delegate)

有时候在测试过程中只返回一个静态的值是不够的,在这种情况下,Do()方法可以用来在方法调用时添加自定义的行为。一般来说,Do()方法会替换方法调用。它的返回值会从模拟的调用中返回(即使是有异常发生也是这样)。Do()的参数委托委托的方法的签名须和方法的签名匹配。只有当签名匹配时才能生效,且一个匹配生效一次。

看官方给出的例子:

public   class  Speaker
{
    
private   readonly   string  firstName;
    
private   readonly   string  surname;
    
private  INameSource nameSource;

    
public  Speaker( string  firstName,  string  surname, INameSource nameSource)
    {
        
this .firstName  =  firstName;
        
this .surname  =  surname;
        
this .nameSource  =  nameSource;
    }

    
public   string  Introduce()
    {
        
string  name  =  nameSource.CreateName(firstName, surname);
        
return   string .Format( " Hi, my name is {0} " , name);
    }
}

  

public   interface  INameSource
{
    
string  CreateName( string  firstName,  string  surname);
}

 

现在演讲者和名字分开在两个类中。然后进行自我介绍,介绍时要介绍自己的姓名,即 FirstName+LastName 。在介绍中要用到 InameSource 中的 CreateName 方法,接下来将会模拟这个接口,而通过其它的方法来替代。

 

[Test]
public   void  SayHelloWorld()
{
    MockRepository mocks 
=   new  MockRepository();
    INameSource nameSource 
=  mocks.DynamicMock < INameSource > ();

    Expect.Call(nameSource.CreateName(
null null ))
          .IgnoreArguments()
          .Do(
new  NameSourceDelegate(Formal));

    mocks.ReplayAll();
    
string  expected  =   " Hi, my name is Ayende Rahien " ;
    
string  actual  =   new  Speaker( " Ayende " " Rahien " , nameSource).Introduce();
    Assert.AreEqual(expected, actual);
}

delegate   string  NameSourceDelegate( string  first,  string  surname); 

private   string  Formal( string  first,  string  surname)
{
    
return  first  +   "   "   +  surname;
}

 

看上段测试的粗体部分。

Do参数是委托类型,其中这个委托类型委托的方法的签名要和模拟对象中期望的要替换的方法的签名一致,即:

private   string  Formal( string  first,  string  surname)
string  CreateName( string  firstName,  string  surname);

 

两者相匹配。

然后当对演讲者构造时:
new Speaker("Ayende", "Rahien", nameSource)

会对演讲者三个域进行赋值

private   readonly   string  firstName;
private   readonly   string  surname;
private  INameSource nameSource;

 

接下来进行介绍时,调用方法:

public   string  Introduce()
{
    
string  name  =  nameSource.CreateName(firstName, surname);
    
return   string .Format( " Hi, my name is {0} " , name);
}

 

而这个方法则由Do方法的委托参数委托的方法来替代:

private   string  Formal( string  first,  string  surname)
{
    
return  first  +   "   "   +  surname;
}

 

返回FirstName+空格+LastName

 

(二)With

流畅式的期望和验证语法。什么是流畅式?先看例子:

[Test]
public   void  TestFluent()
{
    MockRepository mocks 
=   new  MockRepository();
    var customer 
=  mocks.DynamicMock < ICustomer > ();

    
string  strTemp = string .Empty; 

    With.Mocks(mocks)
        .Expecting(
          
delegate
          {
             Expect.Call(customer.ShowTitle(
"" )).Return( " with 语句 " );
          })
        .Verify(
         
delegate
          {
             strTemp 
=  customer.ShowTitle( "" );
          });

    Assert.AreEqual(
" with 语句 " , strTemp);
}

 

这就是所谓的流畅式。通过匿名委托来实现。如果在匿名委托中完成则会隐匿调用ReplayAll()mocks.VerifyAll()

如果要启用次序,则可使用:ExpectingInSameOrder,例如:

[Test]
public   void  TestFluent()
{
    MockRepository mocks 
=   new  MockRepository();
    var customer 
=  mocks.DynamicMock < ICustomer > ();
    
string  strTemp = string .Empty;
    With.Mocks(mocks).ExpectingInSameOrder(
        
delegate
        {
           Expect.Call(customer.ShowTitle(
"" )).Return( " with 语句 " );
           Expect.Call(customer.Unid).Return(
1 );
        })
       .Verify(
       
delegate
       {
          strTemp 
=  customer.ShowTitle( "" );
          
int  i  =  customer.Unid;
       });

    Assert.AreEqual(
" with 语句 " , strTemp);
}

 

With语句的隐式使用

With可以隐式的创建Mock实例,并自动调用VerifyAll方法。

[Test]
public   void  TestWithMocker()
{
    With.Mocks(
        
delegate
        {
          var customer 
=  Mocker.Current.DynamicMock < ICustomer > ();
          Expect.Call(customer.ShowTitle(
"" )).Return( " with 语句 " );
          Mocker.Current.ReplayAll();

          Assert.AreEqual(
" with 语句 " , customer.ShowTitle( "" ));
        });
}

 

这里才看出With确实很流畅。

下边说一下由显式创建Mock实例来代替隐式创建:

[Test]
public   void  TestWithMockerr()
{
    MockRepository mocks 
=   new  MockRepository();
    With.Mocks(mocks,
       
delegate
       {
          var customer 
=  Mocker.Current.DynamicMock < ICustomer > ();
          Expect.Call(customer.ShowTitle(
"" )).Return( " with 语句 " );

          Mocker.Current.ReplayAll();

          Assert.AreEqual(
" with 语句 " , customer.ShowTitle( "" ));
       });
}

 

没多大区别。在使用Mocker.Current时,不能在嵌套中使用,因为这是个全局的,而With.Mocks会重写Mocker.Current

(三)Record-PlayBack

Rhinomock支持一种通过Using语句来进行录制回放的方式。

[Test]
public   void  TestRecordPlayback()
{
    MockRepository mocks 
=   new  MockRepository();
    var customer 
=  mocks.DynamicMock < ICustomer > ();

    
using  (mocks.Record())
    {
        Expect.Call(customer.ShowTitle(
"" )).Return( " 录制回放 " );
    }

    
using  (mocks.Playback())
    {
        Assert.AreEqual(
" 录制回放 " , customer.ShowTitle( "" ));
    }
}

 

 

博客园大道至简

http://www.cnblogs.com/jams742003/

转载请注明:博客园

目录
相关文章
|
移动开发 监控 开发工具
mPaaS常见问题之pod里使用abstract_target后会报错如何解决
mPaaS(移动平台即服务,Mobile Platform as a Service)是阿里巴巴集团提供的一套移动开发解决方案,它包含了一系列移动开发、测试、监控和运营的工具和服务。以下是mPaaS常见问题的汇总,旨在帮助开发者和企业用户解决在使用mPaaS产品过程中遇到的各种挑战
303 0
|
NoSQL Java Redis
介绍Redis的各种用途以及使用场景
介绍Redis的各种用途以及使用场景 Redis 一、为什么使用 解决应用服务器的cpu和内存压力 减少io的读操作,减轻io的压力 关系型数据库的扩展性不强,难以改变表结构 二、优点: nosql数据库没有关联关系,数据结构简单,拓展表比较容易 nosql读取速度快,对较大数据.
12172 1
|
10月前
|
算法 数据安全/隐私保护
基于AutoEncode自编码器的端到端无线通信系统matlab误码率仿真
本项目基于MATLAB 2022a实现自编码器在无线通信系统中的应用,仿真结果无水印。自编码器由编码器和解码器组成,通过最小化重构误差(如MSE)进行训练,采用Adam等优化算法。核心程序包括训练、编码、解码及误码率计算,并通过端到端训练提升系统性能,适应复杂无线环境。
309 65
|
Java Linux Maven
Maven下载与安装详细教程
Maven下载与安装详细教程
483 0
|
Android开发 Swift iOS开发
深入探索iOS与Android操作系统的架构差异及其对应用开发的影响
在当今数字化时代,移动设备已经成为我们日常生活和工作不可或缺的一部分。其中,iOS和Android作为全球最流行的两大移动操作系统,各自拥有独特的系统架构和设计理念。本文将深入探讨iOS与Android的系统架构差异,并分析这些差异如何影响应用开发者的开发策略和用户体验设计。通过对两者的比较,我们可以更好地理解它们各自的优势和局限性,从而为开发者提供有价值的见解,帮助他们在这两个平台上开发出更高效、更符合用户需求的应用。
|
10月前
|
存储 安全 文件存储
剪切未粘贴成功的文件不见了怎么找回来?
你正在移动文件,使用“剪切”命令准备粘贴到新位置,却发现粘贴操作失败,文件却消失了。这个时候,你可能会觉得非常沮丧,因为你以为文件已经消失得无影无踪。然而,不必过于担心,这种情况其实是可以恢复的。在本文中,我们将介绍几种有效的方式,帮助你找回那些“失踪”的文件,让它们重回你的电脑。
|
机器学习/深度学习 人工智能 自然语言处理
探索AI技术:从基础原理到实际应用的全面剖析
本文旨在为读者提供关于人工智能(AI)技术的全面了解。从探讨AI的基本概念和关键技术入手,逐步深入到AI在不同领域的应用实例,包括医疗、金融和自动驾驶等。同时,文章也详细讨论了当前AI技术面临的伦理问题和社会影响,以及可能的解决方案。最后,本文还展望了AI技术未来的发展趋势,帮助读者更好地理解这一前沿科技的现状与未来。
1006 5
|
机器学习/深度学习 自然语言处理 数据管理
GraphRAG核心组件解析:图结构与检索增强生成
【10月更文挑战第28天】在当今数据科学领域,自然语言处理(NLP)和图数据管理技术的发展日新月异。GraphRAG(Graph Retrieval-Augmented Generation)作为一种结合了图结构和检索增强生成的创新方法,已经在多个应用场景中展现出巨大的潜力。作为一名数据科学家,我对GraphRAG的核心组件进行了深入研究,并在此分享我的理解和实践经验。
593 0
|
安全 网络安全
获取旁站 / C 段:第三方网站(附链接)
获取旁站 / C 段:第三方网站(附链接)
|
存储 安全 算法
【C++ 包装器类 std::atomic 】全面入门指南:深入理解并掌握C++ std::atomic 原子操作 的实用技巧与应用
【C++ 包装器类 std::atomic 】全面入门指南:深入理解并掌握C++ std::atomic 原子操作 的实用技巧与应用
1487 1