我刚刚完成了“单元测试的艺术”这本书,并得到了一个关于测试模式的架构问题。
为了测试是否使用了外部库的方法,本书建议使用接口创建一个包装器。这样您就可以使用界面进行模拟。我为使用.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方法/类创建接口和包装器吗?
答案 0 :(得分:1)
经过大量的嘲笑,我得出结论,嘲笑应该是最后的手段。我发现模拟关系测试太多而不能编码,并且通常会掩盖不可测试的代码。这种与实施相关的测试被认为是脆弱的。在这种情况下,我不会直接使用文件I / O的东西,而是围绕.NET文件I / O创建包装器界面。我将使用真正的依赖项,因为测试机器上存在文件系统。然后,在我的测试Setup()方法中,我将确保满足测试的前提条件,例如创建文件。在拆卸方法中,我将确保完成必要的清理工作。
有时,您无法使用真正的依赖关系 - 例如,您通过网络调用服务。模拟应仅限于此类事物。即使在这种情况下你也不必嘲笑。您可以考虑使用假的 - 基本上为您的测试构建服务的内存版本并使用该版本。