我似乎遇到了Mock.Verify的問題,它認爲沒有調用某個方法,但我可以完全驗證它是否正確。預期的模擬調用一次,但是0次,使用Func(T,TResult)
單元測試:
替代單元測試[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參數除外 - 我的理解是這不能被嘲弄)。但莫克不同意這種方法。
任何想法我錯了嗎?
@NikolaiDante - 現在的Git https://github.com/medmondson/Moq-Func-Issue可用 –
您完全掩蓋一個事實,可運行版本,你的方法'無效IterateFiles(IEnumerable的文件路徑, Func fileFunction, TFileFunctionParameter fileFunctionParameter, FileIterationErrorAction errorAction, out outputs);'是泛型的,需要兩個類型參數'TFileFunctionParameter'和'TFileFunctionOutput'。當你在'Runner'中調用方法時,你應該知道'TFileFunctionParameter'和'TFileFunctionOutput'的替換類型(推理)。 –
...(續)然後,您需要以重現這些推斷類型的方式編寫您的'It.IsAny <>()'表達式(在'Verify'內)。要查找'Runner'內使用的'TFileFunctionParameter'和'TFileFunctionOutput'的值,只需將鼠標懸停在Visual Studio中的方法調用上並讀取類型即可。如果難以閱讀,請檢查生成的IL。你使用什麼版本的C#編譯器和.NET運行時(CLR)? –