Unit testing 单元测试Web Api 2模拟用户
我试图在Api控制器测试中模拟User.Identity 这是我的api方法:Unit testing 单元测试Web Api 2模拟用户,unit-testing,asp.net-web-api,mocking,asp.net-web-api2,Unit Testing,Asp.net Web Api,Mocking,Asp.net Web Api2,我试图在Api控制器测试中模拟User.Identity 这是我的api方法: [Route(Urls.CustInfo.GetCustomerManagers)] public HttpResponseMessage GetCustomerManagers([FromUri]int groupId = -1) { var user = User.Identity.Name; if (IsStaff(user) && gro
[Route(Urls.CustInfo.GetCustomerManagers)]
public HttpResponseMessage GetCustomerManagers([FromUri]int groupId = -1)
{
var user = User.Identity.Name;
if (IsStaff(user) && groupId == -1)
{
return ErrorMissingQueryStringParameter;
}
...
}
我遵循了这篇文章中的建议:设置用户属性
这是我的测试:
[TestMethod]
public void User_Without_Group_Level_Access_Call_GetCustomerManagers_Should_Fail()
{
Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity("Bob", "Passport"), new[] {"managers"});
var response = m_controller.GetCustomerManagers();
Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
}
但是当测试运行时,用户属性总是空的
在调用User.Identity之前,我甚至尝试将用于设置CurrentPrincipal的行移到api方法中,但它仍然为null
我做错了什么?如果这种方法不适用于WebAPI2,那么模拟/模拟用户属性的最佳方法是什么
谢谢 您可以在
ControllerContext.RequestContext.Principal中设置用户:
controller.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity("Bob", "Passport"), new[] {"managers"});
或类似的速记:
controller.User = new GenericPrincipal(new GenericIdentity("Bob", "Passport"), new[] {"managers"});
我确实解决了这个问题,为GetUserId()设置了返回值,而不是答案中投票最多的用户名。很抱歉,oyu将不得不将我使用的假货翻译成你选择的嘲弄工具
Claim claim = new Claim("", userId);
ClaimsIdentity fakeClaimsIdentity = A.Fake<ClaimsIdentity>();
A.CallTo(() => fakeClaimsIdentity.FindFirst(A<string>.Ignored)).Returns(claim);
IPrincipal fakeIPrincipal = A.Fake<IPrincipal>();
A.CallTo(() => fakeIPrincipal.Identity).Returns(fakeClaimsIdentity);
var controller = new AuthorisedServicesController()
{
User = fakeIPrincipal
};
Claim=newclaim(“,userId);
ClaimsIdentity fakeClaimsIdentity=A.Fake();
A.CallTo(()=>fakeClaimsIdentity.FindFirst(A.Ignored)).Returns(claim);
IPrincipal fakeIPrincipal=A.Fake();
A.CallTo(()=>fakeprincipal.Identity).Returns(fakeClaimsIdentity);
var控制器=新授权服务控制器()
{
用户=伪造主体
};
但是,更好的解决方案(如果我再次编写代码)是抽象调用GetUserId的实际代码,这样我就可以插入一个可以进行调用的对象,这很容易模仿。有点像工厂。虽然这是一篇老文章,但我想补充一下我的想法
如果您只想模拟用户身份,则无需使用任何模拟框架,因为您无法使用模拟框架(至少不能使用moq)模拟用户身份
只需分配HttpContext.current
属性,如下所示
HttpContext.Current = new HttpContext(
new HttpRequest("", "http://localhost", ""),
new HttpResponse(null)
);
而HttpContext.Current.User的
HttpContext.Current.User =
new GenericPrincipal(
new GenericIdentity("name"),
new []{"manager","Admin"}
);
现在,HttpContext.Current.User.Identity.Name将在WebAPI的控制器中可用
如果要模拟其他属性或对象,请使用moq或任何其他框架。但是模仿HttpContext就像上面一样简单。以这种方式设置主体后,用户ID不会被设置。我需要设置它,因为在我的测试系统中的逻辑是基于用户ID的。例如,User.Identity.Name
已填充(“Bob”),但未填充User.Identity.GetUserId()
@Ben Hall已经有一段时间了,但我想我没有填充。我认为我的解决方法只是改变逻辑,使用UserName
而不是UserId
@Bart,我确实想出了一个解决方案。见下面的新答案。可能要将其标记为正确答案?