测试调用async方法返回'Value not not null'

时间:2017-12-06 14:48:54

标签: c# unit-testing async-await

我有一个异步方法,我正在尝试进行单元测试,特别是我想测试异步方法返回NoContent响应,因为没有找到客户实体。这是有问题的方法:

    [HttpGet]
    [Route("customers/{customerNumber}")]
    public virtual async Task<IHttpActionResult> Get([FromUri] CustomerNumber customerNumber)
    {
        var customerEntitiesList = _tableStorageService.GetCustomerEntities(customerNumber);
        var customersList = customerEntitiesList.Select(customerEntity => customerEntity.PartitionKey).ToList();
        if (customersList.Any()) {
            return await Task.FromResult(Ok(customersList));
        }
        return await Task.FromResult(ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.NoContent, "No content found.")));
    }

为了澄清,CustomerNumber是一个字符串表示类,如下所示:

[DebuggerDisplay("{ToString()}")]
public class CustomerNumber
{
    public CustomerNumber(string customerNumber);

    public static bool TryParse(string customerNumber, out CustomerNumber parsedCustomerNumber);
    public override string ToString();

    public static implicit operator string(CustomerNumber customerNumber);
    public static implicit operator CustomerNumber(string customerNumber);
}

这是单元测试:

    [Test]
    public async Task Should_Return_No_Content_If_Customer_Entities_Are_Not_Found()
    {
        const string customerNumber = "WP0000000000";
        var customerEntitiesStub = new List<CustomerEntity>();
        A.CallTo(() => _tableStorageServiceDummy.GetCustomerEntities(customerNumber)).Returns(customerEntitiesStub);

        var result = await _companyController.Get(customerNumber);

        ((ResponseMessageResult)result).Response.StatusCode.Should().Be(HttpStatusCode.NoContent);
    }

当我运行此测试时,它甚至在完成错误System.ArgumentNullException : Value cannot be null.之前就失败了。为什么会发生这种情况?如何解决这个问题以便我可以断言结果呢?谢谢!

1 个答案:

答案 0 :(得分:0)

模拟设置为期望string,但实际方法具有CustomerNumber参数。开始在那里调查。

由于设置不匹配,调用customerEntitiesListnullGetCustomerEntities

假设CustomerNumber可以从字符串中隐式转换,那么应该使用实际的CustomerNumber实例配置测试。

[Test]
public async Task Should_Return_No_Content_If_Customer_Entities_Are_Not_Found() {
    const CustomerNumber customerNumber = "WP0000000000";
    var customerEntitiesStub = new List<CustomerEntity>();
    A.CallTo(() => _tableStorageServiceDummy.GetCustomerEntities(customerNumber)).Returns(customerEntitiesStub);

    var result = await _companyController.Get(customerNumber);

    ((ResponseMessageResult)result).Response.StatusCode.Should().Be(HttpStatusCode.NoContent);
}

另外,不是该动作的设计将结果包装在任务中。目前没有理由认为该行动是异步的。

[HttpGet]
[Route("customers/{customerNumber}")]
public virtual IHttpActionResult Get([FromUri] CustomerNumber customerNumber)
{
    var customerEntitiesList = _tableStorageService.GetCustomerEntities(customerNumber);
    var customersList = customerEntitiesList.Select(customerEntity => customerEntity.PartitionKey).ToList();
    if (customersList.Any()) {
        return Ok(customersList);
    }
    return Request.CreateErrorResponse(HttpStatusCode.NoContent, "No content found.");
}

并相应地更新测试。