模拟ApplicationUserManager在ASP中的单元测试.. NET Web Api
本文关键字:单元测试 NET Web Api ApplicationUserManager ASP 模拟 | 更新日期: 2023-09-27 18:12:38
我有以下控制器(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);
}