如何使用Moq模拟对具体对象的函数调用?

时间:2010-03-17 13:37:02

标签: unit-testing mocking tdd moq

我如何在Moq中执行此操作?

Foo bar = new Foo();
Fake(bar.PrivateGetter).Return('whatever value')

似乎我只能找到如何模拟通过框架创建的对象。我想在我创建的具体对象上只模拟一个方法/属性。

在TypeMock中,我只会做Isolate.WhenCalled(bar.PrivateGetter).Returns('whatever value')

有什么想法吗?

3 个答案:

答案 0 :(得分:53)

您应该使用Moq创建Mock对象并将CallBase属性设置为true以使用对象行为。

从Moq文档中: CallBase定义为“如果没有期望覆盖成员,则调用基类实现。这被称为“部分模拟”。它允许模拟某个类的某些部分,而不必模拟所有内容。

示例代码:

    [Test]
    public void FailintgTest()
    {
        var mock = new Moq.Mock<MyClass>();
        mock.Setup(m => m.Number).Returns(4);
        var testObject = mock.Object;
        Assert.That(testObject.Number, Is.EqualTo(4));
        Assert.That(testObject.Name, Is.EqualTo("MyClass"));
    }

    [Test]
    public void OKTest()
    {
        var mock = new Moq.Mock<MyClass>();
        mock.Setup(m => m.Number).Returns(4);
        mock.CallBase = true;
        var testObject = mock.Object;
        Assert.That(testObject.Number, Is.EqualTo(4));
        Assert.That(testObject.Name, Is.EqualTo("MyClass"));
    }

    public class MyClass
    {
        public virtual string Name { get { return "MyClass"; } }

        public virtual int Number { get { return 2; } }
    }

答案 1 :(得分:13)

只有TypeMock Isolator(也许是Moles)可以执行这些特技。普通的动态模拟库可以only mock virtual and abstract members

答案 2 :(得分:3)

只要签名上的类型可见,Moles也可以替换私有方法。所以在这种情况下,它看起来像这样:

MFoo bar = new MFoo { // instantiate the mole of 'Foo'
    PrivateGetterGet = () => "whatever value" // replace PrivateGetter {get;}
};
Foo realBar = bar; // retrive the runtime instance
...

如果您正在寻找有关Moles的更多信息,请从http://research.microsoft.com/en-us/projects/pex/documentation.aspx处的教程开始。