无法验证Web API 2.0的返回值

时间:2019-01-07 02:30:53

标签: c# unit-testing asp.net-web-api moq

我正在创建C#Web API 2.0。以及测试项目。该API工作正常。当我运行测试项目并将鼠标悬停在contentResult(这是从API返回的值)上时,它具有正确的值。但是,所有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'的异常           格式化程序:'(((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).Formatters'   引发类型为'System.InvalidOperationException'的异常           请求:“(((System.Web.Http.Results.OkNegotiatedContentResult)actionResult).Request”   引发类型为'System.InvalidOperationException'的异常

1 个答案:

答案 0 :(得分:0)

您在测试中使用了错误的类型。

在被测系统中,您返回

return Ok(_deliveryCode);

_deliveryCode

IDeliveryCode _deliveryCode;

因此返回类型为

OkNegotiatedContentResult<IDeliveryCode> //Interface

在测试中,您尝试将其投射到

OkNegotiatedContentResult<DeliveryCodeValue> //Concrete implementation

这将导致

var contentResult = actionResult as OkNegotiatedContentResult<DeliveryCodeValue>;

null

将代码更改为

var contentResult = actionResult as OkNegotiatedContentResult<IDeliveryCode>;

,它应该表现出预期的效果。

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

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

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