代码改变世界

RhinoMock入门(4)——属性,方法和方法选项(转载)

2013-08-08 10:54  mch.zhang  阅读(367)  评论(0)    收藏  举报

RhinoMock入门(4)——属性,方法和方法选项

(一)属性Property

属性也是一种方法。所以对于属性的期望,和方法是一样的。方法和属性的期望在前几篇随笔中已经大量使用。

通常的读或写属性器的期望

[Test]
publicvoid TestEvent()
{
    MockRepository mocks
=new MockRepository();
    IList
<int> _list = mocks.DynamicMock<IList<int>>();

    Expect.Call(_list.Count).Return(
5);
    mocks.ReplayAll();
    Assert.AreEqual(
5, _list.Count);
}

 

这个是很简单的。然后还有一种自动属性期望的,设置属性行为来达到自动属性期望安装。这个有两种方式,在前边说Mock四种类型时说过:

一是传统的一个一个的安装,还有一种方式就是通过Stub方式实现。

publicinterface ICustomer
{
   
int Unid { get; set; }
   
string CustomerName { get; set; }
   
string Address { get; set; }
   
string ShowTitle(string str);
}
 

 

这个接口有3个属性。

[Test]
publicvoid TestProperty()
{
    MockRepository mocks
=new MockRepository();
    var customer
= mocks.DynamicMock<ICustomer>();
   
using (mocks.Record())
    {
         Expect.Call(customer.Unid).PropertyBehavior();
         Expect.Call(customer.CustomerName).PropertyBehavior();
         Expect.Call(customer.Address).PropertyBehavior();
    }

    customer.Unid
=5;
    Assert.AreEqual(
5, customer.Unid);
}

 

通过这种方法要分别为mock对象设置属性行为。而通过Stub则很简单:

[Test]
publicvoid TestPropertyStub()
{
    MockRepository mocks
=new MockRepository();
    var customer
= mocks.Stub<ICustomer>();  

    customer.Unid
=5;
    Assert.AreEqual(
5, customer.Unid);
}
 

 

通过PropertyBehavior()方法可以为属性模拟行为。这上行为会在模拟对象的生命周期内有效。模拟对象(mock object)与模拟(mock)是两个概念。

(二)方法

属性器有读和写属性,在安装期望时,只是对写属性设置即可。在方法中有多种情况:

1)无返回值

void NoValues(string str);

 

安装期望:

Expect.Call(delegate { customer.NoValues(""); });

 

2)带返回值

这个前边已经大量使用

string ShowTitle(string str);

 

安装期望:

Expect.Call(customer.ShowTitle("")).Return("为空");

3)带输出参数或引用参数的方法

 

[Test]
publicvoid TestOutPara()
{
    MockRepository mocks
=new MockRepository();
    var customer
= mocks.DynamicMock<ICustomer>();
   
string strOut="123";

    Expect.Call(customer
          .OutParas(
"", out strOut))
          .Return(
"test").OutRef("xxx");

    mocks.ReplayAll();
    customer.OutParas(
"", out strOut);
    Assert.AreEqual(
"xxx", strOut);
}
 

 

看粗体部分。带输出或引用参数的方法安装期望和正常调用的方式相似。

这里说明一下,RhinoMock3.5支持lambda和3.x扩展属性,所以在安装时可以这样:

customer.Expect(p => p.OutParas("", out strOut)).Return("test").OutRef("xxx");

 

这个要结合Action<T>和Func<Tresult>来分析,尤其是Action<T>。

(三)方法选项

可以对安装期望的方法设置选项(options),例如:安装完期望的方法的可调用次数。

设置方法是:Expect.Call或LastCall

这里分别说一下:

1Return

当然最长见的就是返回值,为读属性或带返回值的方法返回值设置,与期望匹配。

[Test]
publicvoid TestMethodOptions()
{
    MockRepository mocks
=new MockRepository();
    var customer
= mocks.DynamicMock<ICustomer>();

   
using (mocks.Record())
    {
        Expect.Call(customer.Unid)
              .Return(
10);
    }

    Assert.AreEqual(
10, customer.Unid);
}
 
 

 

 

2Throw

异常抛出。

[Test]
publicvoid TestMethodOptions()
{
    MockRepository mocks
=new MockRepository();
    var customer
= mocks.DynamicMock<ICustomer>();

   
using (mocks.Record())
    {
         Expect.Call(customer.ShowTitle(
""))
               .Throw(
new Exception("不能为空"));
    }

    customer.ShowTitle(
"");
}
 

 

结果:failed: System.Exception : 不能为空

3)方法允许使用的次数

[Test]
publicvoid TestMethodOptions()
{
    MockRepository mocks
=new MockRepository();
    var customer
= mocks.DynamicMock<ICustomer>();

   
using (mocks.Record())
    {
       Expect.Call(customer.ShowTitle(
""))
             .Return(
"不能为空")
             .Repeat.Once();
    }

    Assert.AreEqual(
"不能为空",customer.ShowTitle(""));
    Assert.AreEqual(
"不能为空", customer.ShowTitle(""));
}
 
 

 

安装期望时,允许调用1次。所以对于两次断言使用,会有异常出现。除了Once,还有Twice(),Any等

 

4)忽略方法参数

 

 [Test]
publicvoid TestMethodOptions()
{
    MockRepository mocks
=new MockRepository();
    var customer
= mocks.DynamicMock<ICustomer>();
   
using (mocks.Record())
    {
        Expect.Call(customer.ShowTitle(
null))
              .Return(
"不能为空")
              .IgnoreArguments();
    }

    Assert.AreEqual(
"不能为空", customer.ShowTitle(""));
}
 

请看粗体部分,忽略了字串参数。

5)简单的自动属性

PropertyBehavior()已经说过,不再赘述