Moq - mock.Object.MyMethod模拟不起作用

时间:2012-03-21 09:03:28

标签: c# mocking moq

我有一个奇怪的麻烦。我对Moq不太熟悉,更像是一个GUI人。我试图在我的代码中模拟一个工厂方法。工厂看起来像这样,并返回执行许多IO操作的ISettings实例。我希望它返回一个只有内存的ISettings实例来加速我的测试。

public class SettingsFactory
{
    internal ISettings mSettingsImpl;
    internal virtual ISettings CreateOrGetSettings()
    {
        return mSettingsImpl ?? (mSettingsImpl = new XmlSettings());
    }
}

,模拟是

var imocked = new Mock<SettingsFactory>() {CallBase = false};
imocked.Setup(x => x.CreateOrGetSettings()).Returns(new NonPersistingSettings());
var tryToSeeTheType = imocked.Object.CreateOrGetSettings();
然而,tryToSeeTheType是XMLSettings而不是NonPersistingSettings,正如我所料。将结果逐步显示到代码中,向我显示它直接进入原始工厂方法。我在这里做错了什么建议?

1 个答案:

答案 0 :(得分:0)

模拟对象的“Object”属性实际上并不是您尝试模拟的类的实例。

模拟的目的是能够替换您尝试测试的方法依赖的对象。

想象一下,您的SettingsFactory执行非常昂贵的操作,例如访问网络或数据库或文件系统。您不希望测试访问这些昂贵的资源,因此您创建了一个模拟。我会是这样的:

public class ClassThatUsesSettingsFactory
{
    private readonly SettingsFactory _settingsFactory;

    public ClassThatUsesSettingsFactory(SettingsFactory settingsFactory)
    {
       _settingsFactory = settingsFactory;
    }

    public void MethodThatCallsSettingsFactory()
    {
       //... do something
       var settings = _settingsFactory.CreateOrGetSettings();
       //... do something
    }
}

通过执行此操作,您可以在单元测试中使用模拟替换SettingsFactory,如下所示:

[TestMethod]
public void MakeSureSettingsFactoryIsCalled()
{
   var settingsFactoryMock = new Mock<SettingsFactory>();

   settingsFactoryMock.Setup(f => f.CreateOrGetSettings(), Times.Once).Verifiable();

   var subjectUnderTest = new ClassThatUsesSettingsFactory(settingsFactoryMock.Object);

   subjectUnderTest.MethodThatCallsSettingsFactory();

   settingsFactoryMock.Verify();
}

这个单元测试基本上只是确保方法CreateOrGetSettings被调用一次,而且当MethodThatCallsSettingsFactory被执行时只调用一次。

Moq所做的是创建一个具有不同虚拟方法实现的不同类,一旦调用它,很可能会将标志设置为true,然后在“Verify”方法上检查该标志的值。

这里有很多东西需要掌握,所以我希望它很清楚,因为你提到你没有很多Moq的经验。