制作用于模拟dotnet库的接口

时间:2013-09-28 19:34:39

标签: .net unit-testing mocking

我刚刚完成了“单元测试的艺术”这本书,并得到了一个关于测试模式的架构问题。

为了测试是否使用了外部库的方法,本书建议使用接口创建一个包装器。这样您就可以使用界面进行模拟。我为使用.net方法File.Exists

做了一个例子
public interface IFile
{
    bool Exists(string path);
}


public class File : IFile
{
    bool IFile.Exists(string path)
    {
        return System.IO.File.Exists(path);
    }
}


[TestMethod]
[ExpectedException(typeof(System.IO.FileNotFoundException))]
public void Constructor_WithNonExistingFile_ThrowsFileNotFoundException()
{
    Mock<IFile> fileMock = new Mock<IFile>();
    Mock<ICompositionContainer> compositionMock
        = new Mock<ICompositionContainer>();

    fileMock.Setup(f => f.Exists(It.IsAny<string>())).Returns(false);

    Loader<object> loader = new Loader<object>(
        "testfile",
        fileMock.Object,
        compositionMock.Object);
}

我的问题是,如果这是一个好习惯,如果是这样,我应该为我想要测试的所有.net方法/类创建接口和包装器吗?

1 个答案:

答案 0 :(得分:1)

经过大量的嘲笑,我得出结论,嘲笑应该是最后的手段。我发现模拟关系测试太多而不能编码,并且通常会掩盖不可测试的代码。这种与实施相关的测试被认为是脆弱的。在这种情况下,我不会直接使用文件I / O的东西,而是围绕.NET文件I / O创建包装器界面。我将使用真正的依赖项,因为测试机器上存在文件系统。然后,在我的测试Setup()方法中,我将确保满足测试的前提条件,例如创建文件。在拆卸方法中,我将确保完成必要的清理工作。

有时,您无法使用真正的依赖关系 - 例如,您通过网络调用服务。模拟应仅限于此类事物。即使在这种情况下你也不必嘲笑。您可以考虑使用假的 - 基本上为您的测试构建服务的内存版本并使用该版本。