如何使用 Rhino Mocks 来检查传递给方法的值
我是模拟新手,并且很难解决单元测试的问题。
假设我有这段代码:
public class myClass{
private IDoStuff _doer;
public myClass(IDoStuff doer){
_doer = doer;
}
public void Go(SomeClass object){
//do some crazy stuff to the object
_doer.DoStuff(object) //this method is void too
}
}
好的,所以我想对 Go 方法进行单元测试。我不关心 _doer 对象一旦获取它就会对该对象执行什么操作。
但是,我确实想检查 _doer 对象收到的内容。
在伪代码中我想实现这一点:
[Test]
public void MyTest()
{
IDoStuff doer = Mocker.Mock<IDoStuff>();
Guid id = Guid.NewGuid();
//test Go method
new MyClass(doer).Go(new SomeClass(){id = id});
Assert.AreEqual(id,MockingFramework.Method(DoStuff).GetReceived<SomeClass>().id);
}
使用Rhino是否可以实现这一点,如果可以,我该如何实现?
干杯
I'm new to mocking, and I'm having a hard time solving an issue with UnitTesting.
Say I have this code:
public class myClass{
private IDoStuff _doer;
public myClass(IDoStuff doer){
_doer = doer;
}
public void Go(SomeClass object){
//do some crazy stuff to the object
_doer.DoStuff(object) //this method is void too
}
}
Ok, so I want to UNIT test the Go method. I don't care what the _doer object does to the object once is gets it.
HOWEVER, I do want to inspect what the _doer object has received.
in PSEUDO code I want to achieve this:
[Test]
public void MyTest()
{
IDoStuff doer = Mocker.Mock<IDoStuff>();
Guid id = Guid.NewGuid();
//test Go method
new MyClass(doer).Go(new SomeClass(){id = id});
Assert.AreEqual(id,MockingFramework.Method(DoStuff).GetReceived<SomeClass>().id);
}
Is this possible using Rhino, and if so, how do I achieve it?
cheers
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用新的 Arrange/Act/Assert 语法:
With the new Arrange/Act/Assert syntax:
所有这些答案都提供了多种方法来完成您想做的事情,并且所有这些方法都有效。还有一件事需要注意。如果您需要真正的“低级别”并检查传递给任何存根/模拟方法的参数,您可以使用
GetArgumentsForCallsMadeOn
。它有点混乱,因为它返回 object[][]。您可以像这样使用它(假设您存根
stubber.InsertData
以接受 null):args[0] 是第一次调用时传递给 InsertData 的参数数组。
args[1] 是第二次调用时传递给 InsertData 的参数数组。
等等...
因此,如果您想查看作为某个方法的第一次调用的第二个参数传递的整数值,您可以:
同样,我建议使用前面的方法之一,但是如果您需要真正了解,则可以使用此方法沮丧和肮脏地检查参数。
All of these answers provide various ways to do what you want and all of them work. There's one additional thing to be aware of. If you need to get really "low level" and check out arguments passed to any stubbed/mocked method, you can use
GetArgumentsForCallsMadeOn
.It's a little messy as it returns object[][]. You use it like this (assuming you stubbed
stubber.InsertData
to accept null):args[0] is an array of parameters passed to InsertData the first time it was called.
args[1] is an array of parameters passed to InsertData the second time it was called.
etc...
So if you wanted to see the integer value passed as the second parameter of the first invocation of some method you could:
Again, I'd recommend one of the previous methods, but this is available if you need to get really down and dirty to check out arguments.
我认为你所拥有的很好,所以它是:
然后通过以下方式设置期望:
然后在最后:
根据李的答案编辑,请注意,当你不想要精确的时候,你也可以做类似的事情:
或
或类似的测试使用 Arg 和 Arg 对象进行引用比较。
I think what you have is good so it'd be:
then set up the expectation via:
then at the end:
EDITED from Lee's answers to note that you can also do stuff like:
or
or similar tests when you don't want exact reference comparisons by using the Arg and Arg objects.
仅一个建议:
来自 Wim Coenen 和 Patrick Steele 是正确的,但是,对于第一个解决方案,当只有一个参数时非常快,有测试失败时会出现不正确的错误消息。
这是我的函数的一条消息,带有两个参数:
现在,这两个参数中哪一个是错误的?如果参数更多呢?
我已经用这段代码准备了测试:
所以,在这种情况下,消息是:
嗨
Only a suggestion:
both solution from Wim Coenen and Patrick Steele are correct but, for first solution, very fast when there is only one parameter, there are an incorrect error message when test fails.
This is a message for my function with two parameters:
Now, which of the two parameters is wrong? And what about if parameters were more?
I've prepared test with this code:
So, in this case the message is:
Hi
如果您只想测试
MyClass
实例是否将其参数传递给doer.Go
那么您可以设置一个期望:但是,如果您想检查它是否传递了一些参数可能具有某些特定属性值的不同对象,那么您可以使用约束:
If you just want to test that the
MyClass
instance passes its parameter todoer.Go
then you can just set up an expectation:However if you want to check that it passes some possibly different object with some particular value for a property, then you can use a constraint: