天天看点

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

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>

(1)StrictMock

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

例如:

[Test]

public void TestStrictMock()

{

    MockRepository mocks = new MockRepository();

    ICustomer customer = mocks.StrictMock<ICustomer>();

    customer.Replay();

    customer.ShowTitle("");

    mocks.VerifyAll();

}

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

(2)DynamicMock

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

同样以上个例子来说:

public void TestDynamicMock()

    ICustomer customer = mocks.DynamicMock<ICustomer>();

    mocks.VerifyAll();    

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

(3)PartialMock

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

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

public abstract class ProcessorBase

    public int Register;

    public virtual int Inc()

    {

      Register = Add(1);

      return Register;

    }

    public abstract int Add(int i);

public void TestPartialMock()

    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);

    Assert.AreEqual(2, proc.Register);

(4)Stub

直接以例子进行

public interface IAnimal

    int Legs { get; set; }

    int Eyes { get; set; }

    string Name { get; set; }

    string Species { get; set; }

    event EventHandler Hungry;

    string GetMood();

public class AnimalTest

   IAnimal _animal;

   public AnimalTest(IAnimal animal)

   {

       _animal = animal;

   }

   public void SetLegs(int count)

       _animal.Legs = count;

测试:

public void CreateAnimalStub()

    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来设置,那就简单了:

    IAnimal animal = mocks.Stub<IAnimal>(); 

当然,也可利用反射来封装对象属性行为设置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/

转载请注明:博客园

继续阅读