如何在ASPMVC 5(Microsoft.AspNet.Identity)中存根User.Identity.GetUserId()以进行MVC5控制器的单元测试?GetUserId()是一个扩展,所以我不能直接嘲笑它。我需要在测试前分配Id。似乎您必须创建一个Claim并将其分配给GenericIdentity。但是对于一个单元测试来说似乎有很多事情要做。你知道其他选择吗?
非常感谢您的想法。我使用的是NSubstitute。我既没有Microsoft Fakes也没有JustLock。因此,我结束了直接向GenericIdentity填充声明,这样我就可以控制UserId:的值
string username = "username";
string userid = Guid.NewGuid().ToString("N"); //could be a constant
List<Claim> claims = new List<Claim>{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", username),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", userid)
};
var genericIdentity = new GenericIdentity("");
genericIdentity.AddClaims(claims);
var genericPrincipal = new GenericPrincipal(genericIdentity, new string[] { "Asegurado" });
controllerContext.HttpContext.User = genericPrincipal;
准备好承受疼痛了吗?
这将在很大程度上取决于您使用的是哪种嘲讽框架。根据我的假设,你正在使用Moq,那么你就有点运气不好了,因为Moq在这方面做得不好。原因是Moq不能模拟扩展方法(实际上它可以,但你不想/不应该想这样做:-)
如果你正在使用另一个类似JustLock的嘲讽框架,那么你的里程数可能会有所不同。根据这一点,这是一个该死的景象比什么更容易遵循。
我发现的最简单的方法(仍然很不容易)是使用Microsoft Fakes
大多数新的标识内容都是使用扩展接口编写的。我一辈子都不明白为什么他们认为这是个好主意,但你来了。
以下是你需要做的。
首先为Microsoft.AspNet.Identity
创建一个Fake程序集。您可以通过右键单击程序集并选择"添加伪造程序集"来完成此操作。这基本上是在组件中行走,并为它在那里找到的所有东西创建垫片和存根。您要做的是填充对GetUserId
的调用,。。实际上这并不难。
然后,你必须对ControllerContext
进行常规的嘲讽,因为它的声音很熟悉。
下面的代码将做你正在寻找的我认为-
using (var context = ShimsContext.Create())
{
Microsoft.AspNet.Identity.Fakes
.ShimIdentityExtensions.GetUserIdIIdentity =
(i) => "Mr. T";
var fakeHttpContext = new Mock<HttpContextBase>();
var fakeIdentity = new GenericIdentity("User");
var principal = new GenericPrincipal(fakeIdentity, null);
fakeHttpContext.Setup(t => t.User).Returns(principal);
var controllerContext = new Mock<ControllerContext>();
controllerContext.Setup(t => t.HttpContext)
.Returns(fakeHttpContext.Object);
var sut = new HomeController();
sut.ControllerContext = controllerContext.Object;
var result = sut.YourTestAction();
Assert.True(result.WhatYouCareAbout);
}
当然,不一定是t.先生
HTH
您可以创建从MvcContrib.TestHelper.Fakes 中的对象继承的伪主体和/或标识
然后你可以做这样的事情:
using (var userManager = _userManagerFactory.CreateUserManager())
{
var userId = Guid.NewGuid().ToString();
var result = userManager.CreateAsync(new IdentityUser() { Id = userId, UserName = "userName" }, "password").Result;
Assert.IsTrue(result.Succeeded, "failed to create user through usermanager");
var fakePrincipal = new FakePrincipal(new FakeClaimIdentity(userId, "userName"), new[] { "SomeRole" });
Assert.IsTrue(fakePrincipal.Identity.IsAuthenticated, "fake user did not come back authenticated");
}
我用来制作虚假声明身份的类是:
using System.Collections.Generic;
using System.Security.Claims;
using MvcContrib.TestHelper.Fakes;
namespace Tests.Unit.Fakes
{
public class FakeClaimIdentity : ClaimsIdentity
{
private readonly FakeIdentity _fakeIdentity;
public FakeClaimIdentity(string id, string userName) : base(userName)
{
_fakeIdentity = new FakeIdentity(userName);
base.AddClaims(new List<Claim>
{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", userName),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", id)
});
}
public override bool IsAuthenticated
{
get { return _fakeIdentity.IsAuthenticated; }
}
public override string Name
{
get { return _fakeIdentity.Name; }
}
public override string AuthenticationType
{
get
{
return _fakeIdentity.AuthenticationType;
}
}
}
}
通过这种方式,还可以测试IsAuthenticated部分(如果您关心身份的有效性)。