使用 Moq 模拟具有条件参数的方法

本文关键字:参数 方法 有条件 Moq 模拟 使用 | 更新日期: 2023-09-27 18:32:40

我有一个正在单元测试的类,以验证特定的异常条件是否得到妥善处理。 为此,我模拟了内部调用以引发异常的方法。

我的模拟设置如下所示:

fr.CallBase = true;
fr.Setup(m => m.PutFile(It.IsAny<IFileConnection>(), It.IsAny<string>(), It.IsAny<string>()))
    .Throws(new System.IO.IOException("Test Exception", new System.Net.Sockets.SocketException()));

这完全符合我想要它做的事情。

但是,现在我想通过仅抛出特定值的异常来测试连续性。 我认为它应该看起来像这样:

fr.Setup(m => m.PutFile(It.IsAny<IFileConnection>(), It.Is<string>(a => a == "foo2.txt"), It.IsAny<string>()))
    .Throws(new System.IO.IOException("Test Exception", new System.Net.Sockets.SocketException()));

。但这似乎行不通。 我做错了什么?

根据请求,整个测试:

[Test]
public void ManualRouteInterruptedInDownloadContinuesOn()
{
    var firstRoute = this.UnitOfWork.GetFirstRoute();
    Route r = this.UnitOfWork.GetRouteByID(firstRoute.RouteID);
    r.RegExMatch = "^foo''d.txt$";
    r.Manual = true;
    r.NotifyOfNewFiles = "me@company.com";
    this.UnitOfWork.Save();
    var fr = new Mock<ManualRouting>(r.RouteID);
    fr.CallBase = true;
    fr.Setup(m => m.GetFile(It.IsAny<IFileConnection>(), It.Is<string>(a => a == "foo2.txt"), It.IsAny<string>()))
        .Throws(new System.IO.IOException("Test Exception", new System.Net.Sockets.SocketException()));
    fr.Object.ExecuteRoute(firstRoute.RouteID);
    Assert.IsTrue(fr.Object.Errors.Count == 1);
    Assert.IsTrue(fr.Object.Matches.Count == 3);
}

使用 Moq 模拟具有条件参数的方法

有人在评论中建议我应该尝试

It.Is<string>(a => Equals(a, "foo2.txt"))

他引用了泛型的一些奇怪之处。 我不知道它是否与泛型有关,但这种更改确实有效。 由于发帖人删除了他的评论,我正在代替他做出答案。

我认为

m.PutFile(It.IsAny<IFileConnection>(), "foo2.txt")

应该工作

fr的内部如何知道以foo2.txt作为文件名调用GetFile? 看起来您正在广泛地设置测试规范(^foo''d.txt$),但您的模拟范围很窄(foo2.txt),难道不应该反过来吗?