RhinoMock入门(3)——4种Mock类型-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

RhinoMock入门(3)——4种Mock类型

简介: MockRespository有四种泛型方法: ·CreateMock ·CreateDynamicMock ·PartialMock ·Stub 在3.5中,三种已经过时的方法分别由以下方法替代: ·StrictMock ·DynamicMock ·PartialMock ·Stub 它们各自对应静态工厂方法: ·MockRepository.

MockRespository有四种泛型方法:

·CreateMock<T>

·CreateDynamicMock<T>

·PartialMock

·Stub

3.5中,三种已经过时的方法分别由以下方法替代:

·StrictMock<T>

·DynamicMock<T>

·PartialMock<T>

·Stub<T>

它们各自对应静态工厂方法:

·MockRepository.GenerateStrictMock<T>

·MockRepository.GenerateMock

·MockRepository.GeneratePartialMock<T>

·MockRepository.GenerateStub<T>

 

 

1StrictMock

通过这个方法可以创建一个具有严格语义的T类型mock对象,如果在使用过程中没有显式的对过程进行录制,则会出错误,并会抛出异常。

例如:

[Test]
public void TestStrictMock()
{
    MockRepository mocks 
= new MockRepository();
    ICustomer customer 
= mocks.StrictMock<ICustomer>();

    customer.Replay();
    customer.ShowTitle(
"");
    mocks.VerifyAll();
}

  

这里没有对customerShowTitle方法显式地安装期望, mock对象又是具有严格语义的对象,所以这里会发生错误,而抛出异常。

 

2DynamicMock

通过这个方法可以创建一个具有动态语义的T类型mock对象,如果在使用过种中没有显式的对过程进行录制,则不会出现异常。如果方法有返回值,那么会返回null0

同样以上个例子来说:

public void TestDynamicMock()
{
    MockRepository mocks 
= new MockRepository();
    ICustomer customer 
= mocks.DynamicMock<ICustomer>();

    customer.Replay();
    customer.ShowTitle(
"");
    mocks.VerifyAll();    
}

  

这里同样没有进行显式的安装期望,但不会出现错误,不会抛出异常。所以当使用动态语义模拟对象时,没有显式安装期望的方法会被忽略。

 

3PartialMock

可以模拟类的一部分。可以独立测试抽象方法。它只能用于类。加一官方描述的话:如果方法上没有设置期望的值,就从一个调用类方法的默认类上去创建一个Mock对象。

现在用例子来说明一下,这个例子通过抽象类来进行,抽象类中有一模板方法,而其中的方法是个抽象的,这里通过官网提供的例子来进行:

 

public abstract class ProcessorBase
{
    
public int Register;
    
public virtual int Inc()
    {
      Register 
= Add(1);
      
return Register;
    }
    
public abstract int Add(int i);
}

  

[Test]
public void TestPartialMock()
{
    MockRepository mocks 
= new MockRepository();
    ProcessorBase proc 
= mocks.PartialMock<ProcessorBase>();
    
using (mocks.Record())
    {
        Expect.Call(proc.Add(
1)).Return(1);
        Expect.Call(proc.Add(
1)).Return(2);
    }   

    proc.Inc();
    Assert.AreEqual(
1, proc.Register);

    proc.Inc();
    Assert.AreEqual(
2, proc.Register);

    mocks.VerifyAll();
}

  

4Stub

直接以例子进行

public interface IAnimal
{
    
int Legs { getset; }
    
int Eyes { getset; }
    
string Name { getset; }
    
string Species { getset; }
    
event EventHandler Hungry;
    
string GetMood();
}

public class AnimalTest
{

   IAnimal _animal;
   
public AnimalTest(IAnimal animal)
   {
       _animal 
= animal;
   }

   
public void SetLegs(int count)
   {
       _animal.Legs 
= count;
   }
}

  

测试:

[Test]
public void CreateAnimalStub()
{

    MockRepository mocks 
= new MockRepository();
    IAnimal animal 
= mocks.DynamicMock<IAnimal>();

    Expect.Call(animal.Legs).PropertyBehavior();
    Expect.Call(animal.Eyes).PropertyBehavior();
    Expect.Call(animal.Name).PropertyBehavior();
    Expect.Call(animal.Species).PropertyBehavior(); 

    AnimalTest aa 
= new AnimalTest(animal);
    aa.SetLegs(
10);

    Assert.AreEqual(
10, animal.Legs);
}

  

设置接口属性行为,可以在实例中使用。这个属性行为可以通过Stub来设置,那就简单了:

[Test]
public void CreateAnimalStub()
{
    MockRepository mocks 
= new MockRepository();
    IAnimal animal 
= mocks.Stub<IAnimal>(); 

    AnimalTest aa 
= new AnimalTest(animal);
    aa.SetLegs(
10);
    Assert.AreEqual(
10, animal.Legs);
}

  

当然,也可利用反射来封装对象属性行为设置mock对象的所有属性:

public void SetPropertyBehaviorOnAllProperties(object mock)
{
    PropertyInfo[] properties 
= mock.GetType().GetProperties();
    
foreach (PropertyInfo property in properties)
    {
       
if(property.CanRead && property.CanWrite)
       {
          property.GetValue(mock, 
null);
          LastCall.On(mock).PropertyBehavior();
       }
    }
}

  

从这里看出Stub是多么的方便。

 

博客园大道至简

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

转载请注明:博客园

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章