2009-12-30 75 views
3

请原谅我的无知。我正在努力学习犀牛。c#Rhino mocks - 这是一个适当的模拟使用吗?

public Foo(Stream stream) 
{ 
    if (stream == null) throw new ArgumentNullException("woot"); 
    if (!stream.CanRead) throw new NotSupportedException("sporkish"); 
    if (!stream.CanSeek) throw new NotSupportedException("monkey"); 
} 

我想通过测试这些例外测试这个函数与NUnit测试。这是模拟对象的适当用法,还是我实际上需要制作一个特殊的继承类Stream?如果嘲笑是适当的,我该如何使用Rhino来做到这一点?我可以弄清楚如何从函数(我认为)返回虚拟值,但不是属性。

回答

5

您可以创建Stream一个模拟这表明它无法读取而不能寻求,如下

MockRepository mocks = new MockRepository(); 

Stream mockStream = mocks.StrictMock<Stream>(); 

Expect.Call(mockStream.CanRead).Return(false); 
Expect.Call(mockStream.CanSeek).Return(false); 

mocks.ReplayAll(); 

// Perform the unit test. 

mocks.VerifyAll(); 

一对夫妇的价值的东西要记住的嘲讽:

  1. 嘲讽不只是创建返回虚拟值的对象。一个好的模拟框架测试一个类的特定成员已被访问。这可让您测试以确定您正在测试的类正在对依赖对象进行正确调用。在上面的例子中,如果在VerifyAll()被调用的时候,您还没有读取的值CanReadCanSeek,则会抛出异常以失败测试。
  2. 对接口进行测试时,Mocking是最有用的。您可以在特定类型中覆盖的行为越少,嘲笑效果就越差。在Stream的情况下,您可以覆盖您关心的属性,因此您可以非常容易地实现创建模拟的目标。如果你想嘲笑一个非虚拟/可重写的属性,你会有一个更难的任务。

您的方案,以测试三个抛出异常,你需要创建两个单独的模拟考试,达到所有代码路径:其中一个出现故障的第一个断言 (!stream.CanRead)和其中一个经过第一断言并且失败了第二个断言(!stream.CanSeek)。

+0

我明白我现在做错了什么。我试图在.Return(false)调用之前使用PropertyBehavior。我想我误解了PropertyBehavior的用法。我仍然是一个小菜鸟。 :) – Amy 2009-12-30 20:04:43

4

这是Mocks的适当用法。你需要三个Mock对象。一个没有stream.CanRead,一个没有stream.CanSeek,两个都是(测试成功)。

不要忘了,这可能涉及到将您使用的Stream的功能分解为单独的界面(以便您可以从界面构建您的模拟对象)。