我一直试图解决这个问题几天但现在无济于事。我正在尝试测试AnObject.AnAction的功能(抢先道歉,我必须混淆类/方法名称。)我的目标是让MyTestObj.do_work(AnObject)在调用时保持实际做任何事情。它有我希望在单元测试环境中调用的代码。
这是我的单元测试代码:
Mock< MyTestObj > myTestObj_mock = new Mock< MyTestObj > ();
myTestObj_mock.Setup( e => e.do_work( It.IsAny< AnObject > () ) );
...
AnObject tester = new AnObject();
tester.anAction( myTestObj_mock.Object );
方法AnObject.AnAction(MyTestObj mto)中的:
...
mto.do_work( this );
...
正是在这个时候,我遇到了这个错误:
System.InvalidCastException : Unable to cast object of type
'myNamespace.AnObject' to type 'System.Delegate'.
MyTestObj.do_work是一种虚拟方法。
我完全不知道为什么会出现这个错误。当NUnit运行它时我已经完成了代码,我确信它崩溃了。它不会再进入代码了。
我真的很难过。有没有人知道发生了什么?
提前致谢!
的 的 *** 更新的 * **
我试图在AnObject.AnAction中创建一个AnObject实例并传递它而不是'this':
...
AnObject test = new AnObject();
mto.do_work( test );
...
这没有任何效果。
答案 0 :(得分:3)
在编写问题时,您无需设置myTestObj_mock.do_work()。
设置用于说,当方法X被称为返回值Y时。或者可选地,当调用方法X时,返回异常Z.问问自己,我真的需要做什么?
这里你没有从方法中返回任何东西:
mto.do_work( this );
另外,这里:
myTestObj_mock.Setup( e => e.do_work( It.IsAny< AnObject > () ) );
您没有为设置定义任何退货。
在这种情况下,您应该能够提供模拟myTestObj_mock而无需定义设置。只需使用安装程序删除该行并再次运行测试。
一个猜测:
如果您定义了安装程序,因为您希望测试确保AnObject.AnAction确实调用do_work方法,那么您需要做的是定义Verify方法而不是Setup,同样:
mock.Verify(foo => foo.Execute("ping"));
或在您的情况下像
myTestObj_mock.Verify(m => m.do_work(It.IsAny< AnObject > ()), Times.AtLeastOnce());
另一个猜测:
如果你定义了mock,因为你传递了一个“this”引用,并期望do_work修改一些“this”参数以便测试通过,那么你不应该在这里嘲笑。请记住,模拟不是对象的实际实例,因此修改此引用的代码永远不会被调用。
答案 1 :(得分:3)
我终于能够使用编译器并使用代码,这就是我找到的。这基本上就是贾尔斯在问题的第一部分所说的。
以下是安装程序的代码提示:
指定模拟类型的设置,以调用值返回方法。
而且,这是Setup
的实际代码public ISetup<T> Setup(Expression<Action<T>> expression)
因此,安装程序实际上将代码设置为Action(基本上是委托)。当运行测试运行器时,它会到达此点并且通常期望将委托提供给Returns方法
public IReturnsResult<TMock> Returns(TResult value)
所以,这从未完成,而不是Mock在整个预期路径上运行并且协商所有代码,然后它返回错误的值。
Sooo,这基本上是Giles解释正确的地方。如果您正在测试是否正在调用do_work方法,那么您希望使用Verify
(它真正使用您的虚假对象作为模拟)。但是,如果没有,那么你甚至不需要设置它,因为它什么都不做。如果是这种情况,那么这段代码可能不应该在特定的代码块中,但您最好对此进行评估。
最后,只有在您真正将对象用作存根时,才应使用Setup方法,只需使用它将逻辑注入代码即可。
希望这有意义并帮助您解决问题。
此外,Callback
可能会在这里使用,具体取决于您正在做什么。但是,我不确定。他们在Moq quickstart
使用版本4.0.10827更新我的尝试...并且没有问题
[Test]
public void teststuff()
{
Mock<MyTestObj> myTestObj_mock = new Mock<MyTestObj>();
myTestObj_mock.Setup(e => e.do_work(It.IsAny<AnObject>()));
AnObject tester = new AnObject();
tester.anAction(myTestObj_mock.Object);
}
...
public class MyTestObj
{
public virtual void do_work(AnObject o)
{
}
}
public class AnObject
{
public void anAction(MyTestObj obj)
{
obj.do_work(new AnObject());
}
}