我可以使用Moq来获取传递给非模拟对象的公共方法的值吗?

时间:2011-04-04 22:01:40

标签: moq integration-testing

我正在为FluentMigrator编写单元测试。我正在测试一个连续调用n次的方法。我想要做的是获取连续输入并将它们存储在SortedList中,以便我可以验证方法是否按正确顺序调用,然后将这些输入传递给实际方法 - 就像临时重定向一样。但是,在阅读了文档之后,我无法让它发挥作用。

测试中的代码:

        var listOfVersions = new SortedList<int, long>();
        int i = 0;

        var runnerMock = Mock.Get(_runner); // runner is a MigrationRunner
        runnerMock.Setup(r => r.RollbackToVersion(2))
            .Callback((long v) =>
            {
                listOfVersions.Add(i, v);
                i++;
                _runner.RollbackToVersion(v, true);                 });

        _runner.RollbackToVersion(2);  

错误:

System.ArgumentException : Object instance was not created by Moq.
Parameter name: mocked

我来自Moles,在那里浸入一个物体的行为,然后重定向它并不罕见。也许是在Moq?

1 个答案:

答案 0 :(得分:0)

没有。真正嘲弄的框架分为2个阵营。那些可以模拟任何东西的东西,只能模拟接口,抽象/虚拟方法。

这是因为他们使用了非常不同的拦截技术。 Moq,RhinoMocks等使用Castle的动态代理生成器,它所做的一切都创建了一个暴露相同公共接口的实例。它使用它来记录与该对象的交互,以便您可以对其进行验证。可以模拟抽象和虚拟成员,因为它可以从该类派生并阻止对基类的调用。

然而,Moles和TypeMock Isloator直接与IL一起玩。我知道对于TypeMock,它实际上将IL编织到你试图模拟的方法中,这样你就可以拦截并记录它上面的交互以进行测试(它也会停止对方法的进一步处理)。我知道Moles创建了另一个程序集,你在测试方法中引用它,但我想它与TypeMock的功能非常相似。

如果要模拟具体的不可重写方法,则必须使用后面的框架。