首页 > 解决方案 > 测试 web api 2 时单元测试结果为空对象

问题描述

我是 MS 单元测试和 Moq 对象的新手。我正在尝试测试我的 Web API 2 控制器。我在下面给出了我的单元测试和控制器代码。在单步执行代码时,它甚至没有转到 GetDeliveryCodeStrategy 方法。

[TestMethod]
public void  CreateDelivery_ShouldReturnDeliveryCode()
{
    Mock<IDeliveryStrategy> deliveryStrategy = new Mock<IDeliveryStrategy> 
 ();
    Mock<IDeliveryCode> deliveryCode = new Mock<IDeliveryCode>();
    var controller = new DeliveryCodeController(deliveryStrategy.Object, 
    deliveryCode.Object);
    var controllerContext = new HttpControllerContext();
    var request = new HttpRequestMessage();
    request.Headers.Add("appToken", "a57ffa87-950e-40f4-b965-17788becac7d");

    controllerContext.Request = request;
    controller.ControllerContext = controllerContext;

    var result = controller.CreateDelivery(50) as 
    CreatedNegotiatedContentResult<IDeliveryCode>;
    Assert.IsNotNull(result);

}

public class DeliveryCodeController : ApiController
{
    IDeliveryStrategy _deliveryBatch;
    IDeliveryCode _deliveryCode;

    //Constructor dependency injection through Autofac
   public DeliveryCodeController(IDeliveryStrategy DeliveryBatch, 
   IDeliveryCode deliveryCode)
   {
        _deliveryBatch = DeliveryBatch;
        _deliveryCode = deliveryCode;
   }

   [HttpPost]
   [Route("api/DeliveryCode/{percentage}")]
   public IHttpActionResult CreateDelivery(int percentage)
   {
      String appToken = String.Empty;

    if (Request.Headers.TryGetValues("appToken", out IEnumerable<String> 
    headerValues))
    {
    appToken = headerValues.FirstOrDefault();
    }
    if (!String.IsNullOrEmpty(appToken)))
    {   
    IDeliveryContext deliveryContext = 
       _deliveryBatch.GetDeliveryCodeStrategy(percentage);  
    _deliveryCode.Code = deliveryContext.Create();
    return Created(Request.RequestUri.ToString(), _deliveryCode);    
    }
    else
    {
    return Content(HttpStatusCode.Forbidden, new Error { message = "The App 
    Token is not valid." });
    }
  }

}

当我执行“调试测试”并逐步执行代码时,deliveryContext 对象在代码中为空 IDeliveryContext deliveryContext = _deliveryBatch.GetDeliveryCodeStrategy(percentage);

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

解决方案


您必须设置Mock返回某个值:

IDeliveryContext deliveryContext = // ???? - whatever you want it to be. 
                                   // Could be another Mock.
                                   // This is what the Mock will return.

Mock<IDeliveryStrategy> deliveryStrategy = new Mock<IDeliveryStrategy>();
deliveryStrategy.Setup(x => x.GetDeliveryCodeStrategy(It.IsAny<decimal>()))
    .Returns(deliveryContext);

这告诉Mock它,当它的GetDeliveryCodeStrategy方法被调用时,它应该返回指定的IDeliveryContext. 根据您要执行的操作,这可能是另一个Mock. (返回模拟的模拟是不可取的,但如果你刚开始,我会将这些细节归档并返回。)

我猜那percentage是一个decimal. It.IsAny<decimal>()意味着模拟不关心值是什么。这通常没问题,因为您正在测试的是您的类对模拟返回的对象所做的事情。


推荐阅读