Har*_*rry 4 .net c# unit-testing moq
我试图弄清楚Moq如何或是否可以执行以下操作
public class Download
{
private IFoo ifoo;
public Download(IFoo ifoo)
{
this.ifoo = ifoo;
}
public void Download()
{
var files = Directory.GetFiles("filepath"); //<<<===
foreach (var item in files)
{
// do something
}
}
}
Run Code Online (Sandbox Code Playgroud)
在单元测试中。
// Arrange
var mockFoo = new Mock<IFoo>();
mockFoo.setup( s => s.Bar()).returns(true);
var foo = new Foo(mockFoo.Object);
// Act
foo.Download()
Run Code Online (Sandbox Code Playgroud)
我如何模拟files变量,所以该方法使用模拟版本。这甚至是正确的方法吗?因为我不是在模拟类,而是在模拟依赖关系,所以我该如何设置files变量,以便它查看模拟的文件string []。
您将需要依赖抽象来获取文件,而不是硬依赖于System.IO.Directory:
public interface IFileProvider
{
string[] GetFiles(string path);
}
public class PhysicalFileProvider : IFileProvider
{
public string[] GetFiles(string path)
{
return Directory.GetFiles(path);
}
}
Run Code Online (Sandbox Code Playgroud)
您将以与注入完全相同的方式注入抽象IFoo。现在,您可以IFileProvider使用Moq进行模拟,创建一个模拟,该模拟将完全返回您要返回的字符串。
var fileProvider = new Mock<IFileProvider>();
fileProvider.Setup(x => x.GetFiles(It.IsAny<string>()))
.Returns(new[] {"file1.txt", "file2.txt"});
Run Code Online (Sandbox Code Playgroud)
您还可以使用Microsoft.Extensions.FileProviders.Physical提供文件系统访问和抽象。
public class Download
{
private readonly IFoo _foo;
private readonly Microsoft.Extensions.FileProviders.IFileProvider _fileProvider;
public Download(IFoo foo, IFileProvider fileProvider)
{
_foo = foo;
_fileProvider = fileProvider;
}
public void SomethingWithFiles()
{
var files = _fileProvider.GetDirectoryContents("filepath")
.Where(item => !item.IsDirectory);
foreach (var item in files)
{
// something
}
}
}
Run Code Online (Sandbox Code Playgroud)
具体的实现是PhysicalFileProvider。
另一种变化。代替注入接口,注入委托:
public delegate string[] GetFilesFunction(string path);
public class Download
{
private readonly IFoo _foo;
private readonly GetFilesFunction _getFiles;
public Download(IFoo foo, GetFilesFunction getFiles)
{
_foo = foo;
_getFiles = getFiles;
}
...
Run Code Online (Sandbox Code Playgroud)
这甚至更容易嘲笑。您甚至都不需要起订量。
var subject = new Download(mockedFoo, path => new []{"file1.txt","file2.txt"} );
Run Code Online (Sandbox Code Playgroud)