2016-07-28 139 views
5

我嘲笑抽象类来测试一个类的具体方法如下。我如何模拟UserManager和RoleManager进行单元测试

var mock = new Mock<BaseTestController>(); 
mock.CallBase = true; 
var ta = mock.Object; 

ta.ControllerContext = new HttpControllerContext { Request = new HttpRequestMessage() };   
var owinMock = new Mock<IOwinContext>(); 
owinMock.Setup(o => o.Authentication.User).Returns(new ClaimsPrincipal()); 
owinMock.Setup(o => o.Request).Returns(new Mock<OwinRequest>().Object); 
owinMock.Setup(o => o.Response).Returns(new Mock<OwinResponse>().Object); 
owinMock.Setup(o => o.Environment).Returns(new Dictionary<string, object> { { "key1", 123 } }); 
var traceMock = new Mock<TextWriter>(); 
owinMock.Setup(o => o.TraceOutput).Returns(traceMock.Object); 

ta.Request.SetOwinContext(owinMock.Object); 
var result = await ta.ActivateDeactive("[email protected]", true); 

问题: 我的抽象类使用Entity Framework 6 and Asp.Net Identity UserManager and RoleManager如下

public TestUserManager UserService 
{ 
    get 
    { 
     return _userService ?? Request.GetOwinContext().GetUserManager<TestUserManager>(); 
    } 

    private set 
    { 
     _userService = value; 
    } 
} 

public TestRoleManager RoleService 
{ 
    get 
    { 
     return _roleService ?? Request.GetOwinContext().Get<TestRoleManager>(); 
    } 

    private set 
    { 
     _roleService = value; 
    } 
} 

如何我可以在上面的代码嘲弄嘲弄TestUserManager and TestRoleManager

我尝试了以下方法,但无法获得与controllerContext挂钩的方式。

var userStore = new Mock<IUserStore<TestUser>>(); 
var userManager = new TestUserManager(userStore.Object); 

答复问题问之下由阿列克谢L.

这是怎么TestUserManager派生UserManaer和实施。

public class TestUserManager : UserManager<TestUser> 
{ 
    public TestUserManager(IUserStore<TestUser> store) 
     : base(store) 
    { 
    } 
    public static TestUserManager Create(IdentityFactoryOptions<TestUserManager> options, IOwinContext context) 
    { 
     TestUserManager manager = new TestUserManager(new UserStore<TestUser>(context.Get<AuthContext>())); 
     setValidationRules(manager); 

     IDataProtectionProvider dataProtectionProvider = options.DataProtectionProvider; 
     if (dataProtectionProvider == null) 
      dataProtectionProvider = new DpapiDataProtectionProvider(); 
     manager.UserTokenProvider = new DataProtectorTokenProvider<TestUser>(dataProtectionProvider.Create("ASP.NET Identity")) { TokenLifespan = TimeSpan.FromDays(expiryTime) }; 

     return manager; 
    } 

    public static TestUserManager CreateLocal(AuthContext context) 
    { 
     TestUserManager manager = new TestUserManager(new UserStore<TestUser>(context)); 
     setValidationRules(manager); 

     IDataProtectionProvider dataProtectionProvider = new DpapiDataProtectionProvider(); 
     manager.UserTokenProvider = new DataProtectorTokenProvider<TestUser>(dataProtectionProvider.Create("ASP.NET Identity")); 

     return manager; 
    } 

    private static void setValidationRules(ApplicationUserManager manager) 
    { 
     manager.UserValidator = new UserValidator<TestUser>(manager) 
     { 
      AllowOnlyAlphanumericUserNames = false, 
      RequireUniqueEmail = true 
     }; 

     manager.PasswordValidator = new ApplicationPasswordValidator 
     { 
      RequiredLength = 30, 
      MaximumCharacters = 30, 
      RequireNonLetterOrDigit = false, 
      RequireDigit = true, 
      RequireLowercase = false, 
      RequireUppercase = false 
     }; 
    } 
} 

控制器代码

public async Task<IHttpActionResult> ActivateDeactive(string studentId, bool active) 
{ 
    IdentityResult result; 
    _accountService = new AccountMgtService(UserService, RoleService); 
    result = await _accountService.ActiveDeactiveUser(userId, active); 

} 
+0

显示控制器如何使用'UserManager' –

+0

请检查我的更新问题 - 最后的答案您题。 – immirza

+0

我的意思是控制器的代码。调用'UserManager'的代码 –

回答

5

不知道为什么你正在实施TestUserManager,而不只是嘲笑它。叻说,我们已经在控制器下面的代码:

var owinContext = Request.GetOwinContext(); 
var userManager = owinContext.GetUserManager<ApplicationUserManager>(); 
var applicationUser = userManager.FindById("testId"); 

你可以注入模拟用户存储是这样的:

var owinMock = new Mock<IOwinContext>(); 

var userStoreMock = new Mock<IUserStore<ApplicationUser>>(); 
userStoreMock.Setup(s => s.FindByIdAsync("testId")).ReturnsAsync(new ApplicationUser 
{ 
    Id = "testId", 
    Email = "[email protected]" 
}); 
var applicationUserManager = new ApplicationUserManager(userStoreMock.Object); 

owinMock.Setup(o => o.Get<ApplicationUserManager>(It.IsAny<string>())).Returns(applicationUserManager); 

ta.Request.SetOwinContext(owinMock.Object); 
+0

非常好。但现在我结束了另一个问题...为什么ApplicationUser user = UserManager.FindById(userId);返回null?即使userId存在于数据库表中?我是否需要更多地嘲笑? – immirza

+1

当然,你应该设置模拟用户商店。查看更新的答案。你也可以从问题中删除所有多余的东西,所以它会更容易理解别人 –

+0

优秀的阿列克谢L.从来没有想过会这么容易。谢谢 – immirza