【问题标题】:NullReferenceException in unittesting with NUnit, NSubstitute, and async method使用 NUnit、NSubstitute 和异步方法进行单元测试时出现 NullReferenceException
【发布时间】:2019-04-17 04:38:25
【问题描述】:

我正在使用 NUnit 和 NSubstitute 在 C# 中进行一些单元测试。我有一个名为Adapter 的类,它有一个方法GetTemplates(),我要进行单元测试。 GetTemplates() 使用 httpclient,我使用接口模拟了它。

GetTemplates 中的调用类似于:

public async Task<List<Template>> GetTemplates()
{
    //Code left out for simplificity. 

    var response = await _client.GetAsync($"GetTemplates");

    if (!response.IsSuccessStatusCode)
    { 
        throw new Exception();
    }

}

我希望 _client.GetAsync 返回带有 HttpStatusCode.BadRequestHttpResponseMessage,以便我可以测试是否引发了异常。

测试方法如下:

[Test]
public void GetTemplate_ReturnBadRequestHttpMessage_ThrowException()
{
     //Arrange.
     var httpMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
     _client.GetAsync("").Returns(Task.FromResult(httpMessage));

     //Act.
     var ex = Assert.ThrowsAsync<Exception>(async () => await _Adapter.GetSigningTemplates());

     //Assert.
     Assert.IsInstanceOf<Exception>(ex);
 }

方法运行后返回

System.NullReferenceException:对象引用未设置为对象的实例。

我做错了什么?

【问题讨论】:

    标签: asp.net unit-testing async-await nunit nsubstitute


    【解决方案1】:

    那是因为被模拟的客户端的排列与执行测试时实际调用的不匹配。

    客户期望

    var response = await _client.GetAsync($"GetTemplates");
    

    但设置是为

     _client.GetAsync("")
    

    注意传递的不同参数。当 mock 没有得到确切的设置时,它们通常会返回其返回类型的默认值,在这种情况下为 null

    更改测试以使用预期的参数

    _client.GetAsync($"GetTemplates").Returns(Task.FromResult(httpMessage));
    

    参考Return for specific args

    或使用参数匹配器

    _client.GetAsync(Arg.Any<string>()).Returns(Task.FromResult(httpMessage));
    

    参考Argument matchers

    【讨论】:

    • 谢谢,它正在工作。我也意识到我在构造函数中的顺序错误。
    猜你喜欢
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2011-02-20
    相关资源
    最近更新 更多