【问题标题】:c# xUnit Moq It.IsAny<object> not mocking as expectedc# xUnit Moq It.IsAny<object> 没有按预期模拟
【发布时间】:2020-02-18 20:45:05
【问题描述】:

以下是一段代码(简单的 HTTP 后调用),我试图在 Azure Function 中模拟:

await httpClient.PostAsync("https://url.com", await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json"));

请注意,httpClient.PostAsync() 函数有两个参数:URL 作为字符串和正文作为对象。

现在,在我的测试中,我像这样模拟这个 POST 调用:

httpClientMock.Setup(s => s.PostAsync(It.IsAny<string>(), It.IsAny<object>())).ReturnsAsync(mockedHttpResponse);

我期待await File.ReadAllTextAsync(Path.Combine(Environment.GetEnvironmentVariable("APP_DIRECTORY"), "file.json") 不会被调用,因为我将它设置为与任何对象一起使用。但是,我的测试用例失败并出现以下异常:

发现 System.ArgumentNullException 并显示消息“值不能为空。 (参数'path1')" 在 System.IO.Path.Combine(String path1, String path2)

当我通过在测试中设置环境变量来提供正确的路径(即使是虚拟路径也不起作用)时,它会起作用。但这似乎不是正确的方法,因为单元测试旨在在各种机器上运行,并且每台机器的基本路径都不同。

【问题讨论】:

  • Moq 只会处理传入的参数,您允许它接受任何对象。创建该对象的方法仍然需要在发送到您的 Moq 函数之前进行评估,这就是发送到 Path.Combine 的无效参数失败的地方。
  • 感谢@JonathonChase!我现在知道了。但是,如何处理这些情况,当然无需重写实际代码?
  • 请出示您的完整测试;否则,我们只是在猜测您是如何设置的。另外,as the unit tests are intended to run in various machines:这意味着它们是集成测试,而不是单元测试。

标签: c# unit-testing mocking moq xunit


【解决方案1】:

File.ReadAllTextAsync() 返回一个字符串,因此您的 MOQ 设置应该将 It.IsAny&lt;string&gt;() 作为第二个参数,而不是 It.IsAny&lt;object&gt;()

【讨论】:

  • 以前试过。没用。请参阅乔纳森对原始问题的评论以获取理由。似乎是对的。
猜你喜欢
  • 2017-08-06
  • 2021-05-21
  • 1970-01-01
  • 2018-09-11
  • 2019-08-08
  • 2015-06-12
  • 1970-01-01
  • 2019-07-17
  • 2014-01-24
相关资源
最近更新 更多