qwe*_*123 0 c# unit-testing mocking
我该如何对这类功能进行单元测试?当然我无法创建真正的文件,我无法对Example类和Func进行任何更改以使其更容易测试.
正如我发现的那样,Exists使用流行的免费框架(如moq)来模拟静态是不可能的.我找到了一些模拟文件系统的框架,如System.IO.Abstractions(https://github.com/tathamoddie/System.IO.Abstractions),但在我发现的所有样本中,方法(如此处CreateDirectory等Exists)都是从模拟中调用的对象,我不知道如何使它适应这种方法(如果可能的话).
public class Example
{
public int Func()
{
if(System.IO.File.Exists("some hard-coded path"))
{
return 1;
}
else
{
return 2
}
}
}
Run Code Online (Sandbox Code Playgroud)
如何在测试中创建一个FileWrapper类并将其作为依赖项传递?
public class Example
{
private IFileWrapper _fileWrapper;
public Example()
: this(new FileWrapper())
{
}
public Example(IFileWrapper fileWrapper)
{
_fileWrapper = fileWrapper;
}
public int Func()
{
if (_fileWrapper.Exists("some path")
{
// etc
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后定义FileWrapper为:
internal class FileWrapper : IFileWrapper
{
public bool Exists(string path)
{
return File.Exists(path);
}
}
Run Code Online (Sandbox Code Playgroud)
和接口IFileWrapper为:
public interface IFileWrapper
{
bool Exists(string path);
}
Run Code Online (Sandbox Code Playgroud)
然后你的测试可以创建一个模拟IFileWrapper并将其传递给你测试的类(在这里使用Moq):
[TestMethod]
public void Func_ShouldCheckFileExists()
{
// Arrange
var mockFileWrapper = new Mock<IFileWrapper>();
mockFileWrapper.Setup(_ => _.Exists(It.IsAny<string>())).Returns(true);
var example = new Example(mockFileWrapper.Object);
// Act
int returnValue = example.Func("test path");
// Assert
Assert.Equals(returnValue, 1);
}
Run Code Online (Sandbox Code Playgroud)
这是一个更多的工作,但你可以建立一个这样的包装器的库,并在你的代码库中重用它们.
如果你真的无法修改你的代码,那么看看微软的Moles项目,或者更新的Fakes项目可能对你有帮助.