【发布时间】:2016-01-22 13:55:46
【问题描述】:
我似乎在使用 Mock.Verify 时遇到问题,我认为某个方法没有被调用,但我可以完全验证它是否被调用。
单元测试:
[Test]
public void IterateFiles_Called()
{
Mock<IFileService> mock = new Mock<IFileService>();
var flex = new Runner(mock.Object);
List<ProcessOutput> outputs;
mock.Verify(x => x.IterateFiles(It.IsAny<IEnumerable<string>>(),
It.IsAny<Func<string, ICsvConversionProcessParameter, ProcessOutput>>(),
It.IsAny<ICsvConversionProcessParameter>(),
It.IsAny<FileIterationErrorAction>(),
out outputs), Times.Once);
}
替代单元测试:(在下面的评论之后)
[Test]
public void IterateFiles_Called()
{
Mock<IFileService> mock = new Mock<IFileService>();
var flex = new Runner(mock.Object);
List<ProcessOutput> outputs;
mock.Verify(x => x.IterateFiles(It.IsAny<string[]>(),
flex.ProcessFile, //Still fails
It.IsAny<ICsvConversionProcessParameter>(),
It.IsAny<FileIterationErrorAction>(),
out outputs), Times.Once);
}
Runner.cs:
public class Runner
{
public Runner(IFileService service)
{
string[] paths = new[] {"path1"};
List<ProcessOutput> output = new List<ProcessOutput>();
service.IterateFiles(paths, ProcessFile, new CsvParam(), FileIterationErrorAction.ContinueThenThrow, out output);
}
public ProcessOutput ProcessFile(string file, ICsvConversionProcessParameter parameters)
{
return new ProcessOutput();
}
}
当我调试时,我可以看到 service.IterateFiles 正在被调用。此外,由于所有参数都标有It.IsAny<T>,因此传递的参数无关紧要(out 参数除外——我的理解是这不能被模拟)。然而,Moq 不同意该方法被调用。
任何想法我哪里出错了?
【问题讨论】:
-
@NikolaiDante - 现在可以在 Git 上运行可运行版本 github.com/medmondson/Moq-Func-Issue
-
您完全隐藏了您的方法
void IterateFiles<TFileFunctionParameter, TFileFunctionOutput>(IEnumerable<string> filePaths, Func<string, TFileFunctionParameter, TFileFunctionOutput> fileFunction, TFileFunctionParameter fileFunctionParameter, FileIterationErrorAction errorAction, out List<TFileFunctionOutput> outputs);是通用的并且需要两个类型参数TFileFunctionParameter和TFileFunctionOutput的事实。当您调用Runner中的方法时,您应该找出TFileFunctionParameter和TFileFunctionOutput被替换(推断)的类型。 -
...(续)然后您需要以重现这些推断类型的方式编写您的
It.IsAny<>()表达式(在Verify内)。要查找Runner中使用的TFileFunctionParameter和TFileFunctionOutput的值,只需将鼠标“悬停”在Visual Studio 中的该方法调用上并读取类型即可。如果难以阅读,请检查生成的 IL。您使用什么版本的 C# 编译器和 .NET 运行时 (CLR)? -
@JeppeStigNielsen - 谢谢,虽然不幸的是 NikolaiDante(下面的答案)击败了你,但你已经成功了。非常感谢您花时间查看。
-
我不明白的是,他的回答修改了
runner中的类型参数,这可能没问题,但我们希望 Moq 能够在不更改runner中的代码的情况下模拟这一点。
标签: c# unit-testing moq