博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RhinoMock入门——Do,With和Record-playback
阅读量:7193 次
发布时间:2019-06-29

本文共 4127 字,大约阅读时间需要 13 分钟。

(一)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://gmvkm.baihongyu.com/

你可能感兴趣的文章
Oracle 12C -- clone a remote pdb
查看>>
MySQL7:视图
查看>>
ubuntu 安装 LAMP环境
查看>>
iOS中Block介绍 基础
查看>>
Mac OS 上设置 JAVA_HOME
查看>>
面向对象
查看>>
小知识~VS2012的xamarin加载失败解决
查看>>
eclipse/MyEclipse 日期格式、注释日期格式、时区问题
查看>>
Spring-IOC注解
查看>>
freemarker的TemplateExceptionHandler使用
查看>>
Git分支管理策略
查看>>
maven学习(上)- 基本入门用法
查看>>
Makefile--基本规则(零)
查看>>
关于HFile的存储结构梳理以及快速定位rowkey
查看>>
Eclipse添加默认的JRE
查看>>
poj1639 Picnic Planning 最小度数限制生成树
查看>>
IntelliJ IDEA 学习(一):IntelliJ IDEA15 破解方法(已验证)
查看>>
java 线程的开始、暂停、继续
查看>>
南京优步上线黄金区域,接单可享更高奖励!
查看>>
Duanxx 的 STM32 学习: 中断向量表操作
查看>>