繁体   English   中英

在 ASP.NET Web Api 中模拟 ApplicationUserManager 进行单元测试

[英]Mock ApplicationUserManager for Unit Testing in ASP.NET Web Api

我有以下控制器(WebApi):

[Authorize]
[RoutePrefix("customers/{custId:guid}/carts")]
public class CartsController : BaseApiController
{
    private IUnitOfWork unitOfWork;

    public CartsController(IUnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
    }

    [HttpGet]
    [Route("", Name = "GetCart")]
    [ResponseType(typeof(CartReturnModel))]
    public async Task<IHttpActionResult> GetCartAsync([FromUri] Guid custId)
    {
        if (User.Identity != null)
        {
            if (User.Identity.IsAuthenticated)
            {
                var user = await this.AppUserManager.FindByNameAsync(User.Identity.Name);

                if (user != null)
                {
                    // restrict access to self and account admins
                    if (user.Customer_Id == custId || User.IsInRole("system_admin") || User.IsInRole("accounts_author") || User.IsInRole("accounts_reviewer"))
                    {
                        var tmr = new System.Diagnostics.Stopwatch();
                        tmr.Start();

                        var cust = await unitOfWork.Customers.GetCustomerByShippingAddress(custId);

                        if (cust != null)
                        {
                            var cart = await unitOfWork.CartItems.GetCustomerCart(cust);

                            tmr.Stop();
                            System.Diagnostics.Debug.WriteLine("GetCartAsync took " + tmr.ElapsedMilliseconds + " ms");

                            return Ok(this.TheModelFactory.Create(cust, cart.ToList()));
                        }

                        return NotFound();
                    }
                    return Unauthorized();
                }
            }
        }
        return NotFound();
    }
}
}

这个控制器派生自一个基本控制器:

public class BaseApiController : ApiController
{
    public BaseApiController()
    {
    }

    private ModelFactory _modelFactory;
    protected ModelFactory TheModelFactory
    {
        get
        {
            if (_modelFactory == null)
            {
                _modelFactory = new ModelFactory(this.Request, this.AppUserManager);
            }
            return _modelFactory;
        }
    }

    private ApplicationUserManager _AppUserManager = null;
    protected ApplicationUserManager AppUserManager
    {
        get
        {
            return _AppUserManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
    }

    private ApplicationRoleManager _AppRoleManager = null;
    protected ApplicationRoleManager AppRoleManager
    {
        get
        {
            return _AppRoleManager ?? Request.GetOwinContext().GetUserManager<ApplicationRoleManager>();
        }
    }



    protected IHttpActionResult GetErrorResult(IdentityResult result)
    {
        if (result == null)
        {
            return InternalServerError();
        }

        if (!result.Succeeded)
        {
            if (result.Errors != null)
            {
                foreach (string error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }
            }

            if (ModelState.IsValid)
            {
                // No ModelState errors are available to send, so just return an empty BadRequest.
                return BadRequest();
            }

            return BadRequest(ModelState);
        }

        return null;
    }
}

过去一周,我一直在尝试对控制器方法 GetCartAsync 进行单元测试。 但它总是返回 Assert.IsNotNull 失败,我不明白为什么。 这是测试:

 [TestMethod]
public async Task GetCart() {
    {
        IList<CartItem> cart = new List<CartItem>()
        {
            new CartItem
                {
                    Id = Guid.Parse("f1f1f790-1d13-4416-b079-5f41bcedc4ab")
                },
                new CartItem
                {
                    Id = Guid.Parse("1294782a-4dd7-4445-a451-590069eaa3aa")
                },
                new CartItem
                {
                    Id = Guid.Parse("e04027e6-70af-45cc-9e16-deec23671c1a")
                }
        };

    var account = new UserAccount { UserName = "m", Email = "m@m.com" };
    var mockAppManager = new Mock<ApplicationUserManager>();
    mockAppManager.Setup(c => c.FindByNameAsync("m")).ReturnsAsync(account);


    var mockRepository = new Mock<jCtrl.Services.IUnitOfWork>();
    mockRepository.Setup(x => x.CartItems.GetCustomerCart(It.IsAny<Customer>(), It.IsAny<bool>())).ReturnsAsync(cart.AsEnumerable());

    var controller = new CartsController(mockRepository.Object){
        Request = new HttpRequestMessage {RequestUri = new Uri("http://localhost/customers/9efa5332-85dc-4a49-b7af-8807742244f1/carts")},
        Configuration = new HttpConfiguration(),
        User = new ClaimsPrincipal(new GenericIdentity("fake_username"))
    };


    controller.Request.SetOwinContext(new OwinContext());

    // Act
    var custId = Guid.Parse("9efa5332-85dc-4a49-b7af-8807742244f1");

    // Act
    var actionResult = await controller.GetCartAsync(custId);
    var contentResult = actionResult as OkNegotiatedContentResult<CartReturnModel>;

    // Assert
    Assert.IsNotNull(contentResult);
    Assert.IsNotNull(contentResult.Content);
    Assert.AreEqual(1, contentResult.Content.ItemCount);
}

关于这里出了什么问题的任何想法。 这让我非常头疼。

您的ApiController.User属性未设置用于测试。

我更惊讶的是User.Identity != null没有给你一个 NRE。 的确。 如果那通过了。 那么它将根据您的测试方法返回一个NotFoundResult

这会导致演员

var contentResult = actionResult as OkNegotiatedContentResult<CartReturnModel>;

null ,导致您的断言失败。

您需要为测试设置一个假User

var controller = new CartsController(mockRepository.Object){
    Request = new HttpRequestMessage { RequestUri = new Uri("http://localhost/customers/9efa5332-85dc-4a49-b7af-8807742244f1/carts"),  },
    Configuration = new HttpConfiguration(),
    User = new ClaimsPrincipal(new GenericIdentity("fake_username"))
};

您还应该使测试异步。

[TestMethod]
public async Task GetCart() {
    //Arrange
    //...other code omitted for brevity
    var username = "m";
    var customerGuid = "9efa5332-85dc-4a49-b7af-8807742244f1"; 
    var account = new UserAccount { UserName = username, Email = "m@m.com" };
    var mockAppManager = new Mock<ApplicationUserManager>();
    mockAppManager.Setup(c => c.FindByNameAsync(username)).ReturnsAsync(account);


    var mockRepository = new Mock<jCtrl.Services.IUnitOfWork>();
    mockRepository.Setup(x => x.CartItems.GetCustomerCart(It.IsAny<Customer>(), It.IsAny<bool>())).ReturnsAsync(cart.AsEnumerable());

    var requestUri = new Uri(string.Format("http://localhost/customers/{0}/carts", customerGuid));
    var controller = new CartsController(mockRepository.Object){
        Request = new HttpRequestMessage {RequestUri = requestUri},
        Configuration = new HttpConfiguration(),
        User = new ClaimsPrincipal(new GenericIdentity(username))
    };


    var custId = Guid.Parse(customerGuid);

   // Act
    var actionResult = await controller.GetCartAsync(custId);
    var contentResult = actionResult as OkNegotiatedContentResult<CartReturnModel>;

    // Assert
    Assert.IsNotNull(contentResult);
    Assert.IsNotNull(contentResult.Content);
    Assert.AreEqual(1, contentResult.Content.ItemCount);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM