犀牛存根不符合期望

时间:2011-12-15 01:32:51

标签: unit-testing rhino-mocks stub

我正在抄写两个不同的对象。以下是接口:

public IInterface1
{
    IEnumerable<Foo> Method1(int p1, string p2 = null, string p3 = null);
}

public IInterface2
{
    Bar Method2(int p3, int? p4 = null);
}

如您所见,两者都有默认为null的参数。但是,一个匹配我的Expect,另一个不匹配。这个存根工作;当使用值匹配testData.p1调用其方法时,它返回一个包含两个Foo的数组:

var obj1 = MockRepository.GenerateStub<IInterface1>();
obj1.Expect(m => m.Method1(
         Arg.Is(testData.p1), 
         Arg<string>.Is.Null, 
         Arg<string>.Is.Null))
    .Return(new[] { new Foo(), new Foo() });

但是,这个类似的存根返回预期的结果,而是返回null,尽管参数符合预期:

var obj2 = MockRepository.GenerateStub<IInterface2>();
obj2.Expect(m => m.Method2(Arg.Is(testData.p3), Arg<int?>.Is.Null))
    .Return(new Bar());

为什么第二个存根与我的参数不匹配?即使我使用Arg<int?>.Is.Anything作为第二个预期参数,仍会返回null

更新

好的,我找到了另一种方法来设置我的期望,传递预期值而不是使用Arg

obj1.Expect(m => m.Method1(testData.p1, null, null))
    .Return(new[] { new Foo(), new Foo() });

obj2.Expect(m => m.Method2(testData.p3, null))
    .Return(new Bar());

当我以这种方式设置它们时,两个存根都会返回预期的结果。我仍然不清楚这种区别以及为什么一个人与Arg合作而另一个人没有合作。我想这是另一个时间,我对这个库中的AAA,记录/重放,模拟和存根的混合感到困惑。任何人都可以消除我对原始代码不起作用的困惑吗?

1 个答案:

答案 0 :(得分:2)

在运行时,当您将null传递给IInterface2的第二个参数时,.NET将创建一个Nullable<int>并将其传递给您的方法实现。然后,您的实现代码可以检查p4.HasValue并执行您想要考虑空值的任何内容。

但是从Rhino.Mocks的立场来看,当它拦截方法调用时,它会看到第二个参数是Nullable<int>(不是空实例),因此你的期望不会匹配。 / p>

在第二次尝试中,当您直接传递null时,运行时将再次将该null包装在Nullable<T>中。 Rhino.Mocks会检查两个参数是否相等(看看你是否有匹配的期望)。 Nullable<T>会覆盖Equals方法,以检查两个Nullable<T>是否都为null并返回true - 从而符合您的预期。