首页 > 解决方案 > 无法验证来自 web api 2.0 的返回值

问题描述

我正在创建一个 C# Web API 2.0。以及一个测试项目。API 工作正常。当我运行测试项目并将鼠标悬停在contentResultAPI 返回的值上时,它具有正确的值。但是,所有的 Assert 语句都失败了。在下面的代码中,我返回一个对象,DeliveryCode. 即使我返回字符串,我也会得到同样的错误。

控制器:

public class CodeGeneratorController : ApiController
{
    ICheckCodeExist _checkCodeExist;
    IGenerateBrandNewCode _generateBrandNewCode;
    IGenerateFromExistingCode _generateFromExistingCode;
    IDeliveryCode _deliveryCode;

    public CodeGeneratorController(ICheckCodeExist checkCodeExist, IGenerateBrandNewCode generateBrandNewCode, IGenerateFromExistingCode generateFromExistingCode, IDeliveryCode deliveryCode)
    {
        _checkCodeExist = checkCodeExist;
        _generateBrandNewCode = generateBrandNewCode;
        _generateFromExistingCode = generateFromExistingCode;
        _deliveryCode = deliveryCode;
    }

    [HttpGet]
    [Route("api/CodeGenerator/{percentage}")]
    public IHttpActionResult Get(int percentage)
    {
        if (_checkCodeExist.IsCodeAvailable(percentage))
        {
            _deliveryCode.Code = _generateFromExistingCode.GetDeliveryCode();                   
            return Ok(_deliveryCode);
        }
        else
        {
            _deliveryCode.Code = _generateBrandNewCode.GetDeliveryCode();
            return Ok(_deliveryCode);
        }            
    }
}

混凝土1级:

public class GenerateFromExistingCode : IGenerateFromExistingCode
{
    public string GetDeliveryCode()
    {
        return "XYZ456";
    }
}

混凝土类 2:

public class GenerateBrandNewCode : IGenerateBrandNewCode
{
    public string GetDeliveryCode()
    {
        return "ABC123";
    }
}

测试

[TestMethod]
public void GetDeliveryCodeWithPercentage()
{
    //Arrange
    Mock<ICheckCodeExist> checkCodeExist = new Mock<ICheckCodeExist>();
    checkCodeExist.Setup(x => x.IsCodeAvailable(50)).Returns(true);             
    var generateBrandNewCode = new GenerateBrandNewCode();
    var generateFromExistingCode = new GenerateFromExistingCode();
    var deliveryCode = new DeliveryCodeValue();

    var codeGeneratorController = new 
    CodeGeneratorController(checkCodeExist.Object, generateBrandNewCode, 
    generateFromExistingCode, deliveryCode);

    //Act
    IHttpActionResult actionResult = codeGeneratorController.Get(50);            
    var contentResult = actionResult as OkNegotiatedContentResult<DeliveryCodeValue>;

    //Assert
    Assert.IsNotNull(contentResult);
    Assert.IsNotNull(contentResult.Content);
    Assert.AreEqual("XYC456", contentResult.Content.Code);
}

错误:

ContentNegotiator -
'((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).ContentNegotiator' 抛出类型为 'System.InvalidOperationException' 的异常 Formatters: '((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).Formatters'引发了“System.InvalidOperationException”类型的异常请求:“((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).Request”引发了“System.InvalidOperationException”类型的异常

标签: c#unit-testingasp.net-web-apimoq

解决方案


您在测试中转换为错误的类型。

在被测系统中,您返回

return Ok(_deliveryCode);

_deliveryCode在哪里

IDeliveryCode _deliveryCode;

因此返回类型将是

OkNegotiatedContentResult<IDeliveryCode> //Interface

在测试中,您尝试将其转换为

OkNegotiatedContentResult<DeliveryCodeValue> //Concrete implementation

这将导致

var contentResult = actionResult as OkNegotiatedContentResult<DeliveryCodeValue>;

将代码更改为

var contentResult = actionResult as OkNegotiatedContentResult<IDeliveryCode>;

它应该按预期运行。

最后,GenerateFromExistingCode.GetDeliveryCode返回"XYZ456",但断言正在检查"XYC456"

Assert.AreEqual("XYC456", contentResult.Content.Code);

验证这确实是所需的断言。


推荐阅读