2016-07-28 110 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