RhinoMock入门(6)——安装结果和约束

简介: (一)安装结果(SetupResult) 有时候在模拟对象中需要一个方法的返回值,而不在意这个方法是否被调用。就可以通过安装结果(SetupRestult)来设置返回值,而绕开期望安装,且可以使用多次。

(一)安装结果(SetupResult

有时候在模拟对象中需要一个方法的返回值,而不在意这个方法是否被调用。就可以通过安装结果(SetupRestult)来设置返回值,而绕开期望安装,且可以使用多次。从依赖的角度来说是这样的:方法a(或属性)被方法b使用,而在其它的位置c处方法a又会被使用,而在c处使用之前,不保证是否在b处使用且修改了方法a的返回值。意思就是保证方法a的返回结果是固定的,是忽略它的依赖,而在它该用的位置使用它恒定的值。安装结果可以达到这种效果。

 

public   class  Customer
{
    
public   virtual   int  DescriptionId{ get ; set ;}
    
public   virtual   void  PrintDescription()
    {
        DescriptionId
= 1 ;
    }
}

 

属性 DesriptionId 被方法 PrintDescription() 依赖。

 

[Test]
public   void  TestSetupResult()
{
    MockRepository mocks 
=   new  MockRepository();
    var customer 
=  mocks.DynamicMock < Customer > ();
    SetupResult.For(customer.DescriptionId).Return(
10 ); 

    Expect.Call(
delegate  { customer.PrintDescription(); }).Repeat.Times( 2 );

    mocks.ReplayAll();

    customer.PrintDescription();
    customer.PrintDescription();

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

 

从这段测试中可以看到,对customerDescriptionId属性进行了结果安装,只让这个属性返回10。而在随后对依赖它的方法进行了期望安装,且可以被调用2次。但DescriptionId的值仍是10

Expect.Call(delegate { customer.PrintDescription(); }).Repeat.Times(2);

这句是对不带返回值的方法进行期望安装,当然可以使用Lambda来进行。这个匿名方法就是一个不带参数,没有返回值的委托,这个就相当于Action<>,通过lambda就是:()=>customer.PrintDescription(),完整就是:

Expect.Call(()=>customer.PrintDescription()).Repeat.Times(2);

关于匿名方法和Action<T>委托可见:

http://www.cnblogs.com/jams742003/archive/2009/10/31/1593393.html

http://www.cnblogs.com/jams742003/archive/2009/12/23/1630737.html

 

安装结果有两种方法:

ForOnFor在上边已经使用,On的参数是mock object。对于上边的示例中的粗体部分用On来实现为:

SetupResult.On(customer).Call(customer.DescriptionId).Return( 10 );

 

这个也可以通过期望的选项来实现。例如:

Expect.Call(customer.DescriptionId).Return( 10 )
      .Repeat.Any()
      .IgnoreArguments();

其中的粗体部分,可以多次使用,且忽略参数。

(二)约束(Constraints

约束用来对期望的参数进行规则约束。系统提供了大量内建的约束方法,当然也可以自定义。这里直接贴一张官网给出的列表,一目了然:

 

约束

说明

例子

接受的值

拒绝的值

Is

任何

Is.Anything()

{0,"","whatever",null, etc}

Nothing Whatsoever

等于

Is.Equal(3)

3

5

不等于

Is.NotEqual(3)

null, "bar"

3

Is.Null()

null

5, new object()

不为无

Is.NotNull()

new object(), DateTime.Now

null

指定类型

Is.TypeOf(typeof(Customer))

or Is.TypeOf<Customer>()

myCustomer, new Customer()

null, "str"

大于

Is.GreaterThan(10)

15,53

2,10

大于等于

Is.GreaterThanOrEqual(10)

10,15,43

9,3

小于

Is.LessThan(10)

1,2,3,9

10,34

小于等于

Is.LessThanOrEqual(10)

10,9,2,0

34,53,99

匹配

Is.Matching(Predicate<T>)

 

 

相同

Is.Same(object)

 

 

不相同

Is.NotSame(object)

 

 

Property

等于值

Property.Value("Length",0)

new ArrayList()

"Hello", null

Property.IsNull

("InnerException")

new Exception

("exception without

 inner exception")

new Exception

("Exception

with inner Exception",

 new Exception("Inner")

不为无

Property.IsNotNull

("InnerException")

new Exception

("Exception with inner Exception",

new Exception("Inner")

new Exception

("exception without

inner exception")

List

集合中包含这个元素

List.IsIn(4)

new int[]{1,2,3,4},

 new int[]{4,5,6}

new object[]{"",3}

集合中的元素(去重)

List.OneOf(new int[]{3,4,5})

3,4,5

9,1,""

等于

List.Equal(new int[]{4,5,6})

new int[]{4,5,6},

new object[]{4,5,6}

new int[]{4,5,6,7}

Text

以…字串开始

Text.StartsWith("Hello")

"Hello, World",

"Hello, Rhino Mocks"

"", "Bye, Bye"

以…字串结束

Text.EndsWith("World")

"World",

"Champion Of The World"

"world", "World Seria"

包含

Text.Contains("or")

"The Horror Movie...",

"Either that or this"

"Movie Of The Year"

相似

Text.Like

("rhino|Rhinoceros|rhinoceros")

"Rhino Mocks",

"Red Rhinoceros"

"Hello world", "Foo bar",

Another boring example string"

 

例子:

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

    Expect.Call(customer.ShowTitle(
"" ))
          .Return(
" 字符约束 " )
          .Constraints(Rhino.Mocks.Constraints
                           .Text.StartsWith(
" cnblogs " )); 

    mocks.ReplayAll();
    Assert.AreEqual(
" 字符约束 " , customer.ShowTitle( " cnblogs my favoured " ));
}

 

它的意思就是如果参数以cnblogs开头,则返回期望值。可以比较一下Moq的参数约束设置方法:

http://www.cnblogs.com/jams742003/archive/2010/03/02/1676197.html

 

除了上述方法外,rhinomock约束还支持组合,即与,非,或。还以上例进行:

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

    Expect.Call(customer.ShowTitle(
"" ))
          .Return(
" 字符约束 " )
          .Constraints(
               Rhino.Mocks.Constraints.Text.StartsWith(
" cnblogs "
            
&&  Rhino.Mocks.Constraints.Text.EndsWith( " ! " )
    ); 

    mocks.ReplayAll();
    Assert.AreEqual(
" 字符约束 " , customer.ShowTitle( " cnblogs my favoured! " ));
}

 

参数的条件就是以cnblogs开头,且以!号结束。

 

博客园大道至简

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

转载请注明:博客园

目录
相关文章
|
机器学习/深度学习 数据采集 算法
时间序列结构变化分析:Python实现时间序列变化点检测
在时间序列分析和预测中,准确检测结构变化至关重要。新出现的分布模式往往会导致历史数据失去代表性,进而影响基于这些数据训练的模型的有效性。
1424 1
|
Java Spring 容器
Spring系列(五):@Lazy懒加载注解用法介绍
@Lazy 懒加载注解的概念 SpringIoC容器会在启动的时候实例化所有单实例 bean 。如果我们想要实现 Spring 在启动的时候延迟加载 bean,即在首次调用bean的时候再去执行初始化,就可以使用 @Lazy 注解来解决这个问题
Spring系列(五):@Lazy懒加载注解用法介绍
Jupyter Notebook 的快捷键
命令模式 (按键 Esc 开启) Enter : 转入编辑模式 Shift-Enter : 运行本单元,选中下个单元 Ctrl-Enter : 运行本单元 Alt-Enter : 运行本单元,在其下插入新单元 Y : 单元转入代码状态 M :单元转入markdown状态 R : 单元转入raw状态...
2234 0
|
8天前
|
人工智能 数据可视化 Java
Spring AI Alibaba、Dify、LangGraph 与 LangChain 综合对比分析报告
本报告对比Spring AI Alibaba、Dify、LangGraph与LangChain四大AI开发框架,涵盖架构、性能、生态及适用场景。数据截至2025年10月,基于公开资料分析,实际发展可能随技术演进调整。
707 150
|
17天前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
1452 39