【问题标题】:Mock interface ReturnsAsync returning null模拟接口 ReturnsAsync 返回 null
【发布时间】:2017-11-07 17:01:21
【问题描述】:

我正在尝试 Mock 一个具有单个 Task<string> 方法的 Interface

这里的 Q 相同,但我似乎无法让代码对我有利:Setup async Task callback in Moq Framework

我的界面是这样的:

public interface IHttpClient
{
    Task<string> GetStringAsync(string uri);
}

我正在尝试这样模拟:

var mockHttp = new Mock<IHttpClient>();
mockHttp.Setup(m => m.GetStringAsync("aPretendUrl")).ReturnsAsync("Some sort of string");

我发现GetStringAsync 的结果是null

在注入此实例的控制器中,我这样称呼它:

string responseData = await _client.GetStringAsync(url);

也在尝试

string responseData = _client.GetStringAsync(url).Result;

responseData 在所有情况下都是null

我确定我错过了一些简单的东西。单元测试仍然是新事物

谁能指出我哪里出错了?

更新

完整的单元测试如下所示:

[Test]
public void Given_EController_Called_With_unknown_pedi_Returns_NotFound()
{
    // Arrange
    AppSettings settings = new AppSettings()
    {
        DataWarehouseAPI = "http://myurl.com"
    };
    Mock<IOptionsSnapshot<AppSettings>> mockSettings = new Mock<IOptionsSnapshot<AppSettings>>();
    mockSettings.Setup(m => m.Value).Returns(settings);

    var mockHttp = new Mock<IHttpClient>();
    mockHttp.Setup(m => m.GetStringAsync("aPretendUrl")).ReturnsAsync("[]");

    EntryController controller = new EntryController(mockHttp.Object, mockSettings.Object);

     // Act
    IActionResult actionResult = controller.GetByPedimento("nothing").Result;

    // Assert
    Assert.IsAssignableFrom<NotFoundObjectResult>(actionResult);
    }

【问题讨论】:

  • 你确定 _client.GetStringAsync(url) 执行时 url 的值是 'aPretendUrl' 吗?
  • 在这种情况下它不应该做任何事情。我试图模拟一个返回特定字符串的实现。我不希望它真的打电话。也许我误解了 Moq 框架?
  • 你向“url”发送什么值?
  • 只有当 url 是“aPretendUrl”时,你的 mock 才会返回“Some sort of string”,并且会为所有其他输入 url 返回 null。你能用你的 UT 来更新你的问题吗?
  • 如果问题是@CodeFuller 所说的,你应该使用mockHttp.Setup(m =&gt; m.GetStringAsync(Is.IsAny&lt;string&gt;())).ReturnsAsync("Some sort of string");

标签: c# unit-testing moq


【解决方案1】:

如果您不关心测试中的“url”,那么您可以使用:

It.IsAny<string>()

结果:

mockHttp.Setup(m => m.GetStringAsync(It.IsAny<string>()))
    .ReturnsAsync("Some sort of string");

如果您在 setup 中指定 'uri' 参数,那么您必须在测试中匹配它才能从方法中获得所需的返回值“某种字符串”。您可以为不同的输入指定不同的结果:

[TestMethod]
public async Task GetStringAsync_moqSetup()
{
    var mockHttp = new Mock<IHttpClient>();

    mockHttp.Setup(m => m.GetStringAsync(It.IsAny<string>()))
        .ReturnsAsync("Other sort of string");
    mockHttp.Setup(m => m.GetStringAsync("first"))
        .ReturnsAsync("First sort of string");

     var firstTarget = await mockHttp.Object.GetStringAsync("first");
     var differentTarget = await mockHttp.Object
         .GetStringAsync("something completely different");

    Assert.AreEqual("First sort of string", firstTarget);
    Assert.AreEqual("Other sort of string", differentTarget);
}

查看框架的Quickstart,以便更好地了解如何使用它。

【讨论】:

  • It.IsAny&lt;string&gt;() 完美运行。现在慢慢开始明白了……慢慢的:)\
  • @Darren,在答案中包含了指向快速入门的链接。您应该花一些时间查看它,以便更好地理解该框架。
  • 你是我的救星:D
猜你喜欢
  • 2021-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多