[英]How to unit test a class using moq that has dependencies within a method?
我想對一個驗證用戶身份的AuthClient
類(使用Moq
)進行單元測試。
問題是我的AuthenticationService
依賴項沒有注入到類中。 我對如何在不注入依賴項的情況下測試流感到困惑。
[TestClass]
public class AuthClient
{
string Dictionary<string, IList<UserPermissions> _userPermissions;
User Login(string username, string password)
{
IAuthenticationService authenticationService = new AuthenticationService();
User user = authService.Login(username, password);
IAuthorizationService authorizationService = new AuthorizationService();
var permissions = authorizationService.GetPermissions(user);
_userPermissions.Add(user.Username, permissions);
return user;
}
}
我當前的單元測試代碼如下:
public class UnitTestClass
{
public string UserName {get;set;}
public string Password {get;set;}
[TestInitialize]
public void Setup()
{
UserName = "test";
Password = "test123";
}
[TestMethod]
public void When_ValidUserCredentials_Expect_UserIsNotNull()
{
var mockAuthenticationService = new Mock<IAuthenticateService>();
mockAuthenticationService.Setup(m => m.Login(ValidUserName, ValidPassword)).Returns(ValidUserDto);
var mockAuthorizationService = new Mock<IAuthorizeService>();
mockAuthorizationService.Setup(m => m.GetAllPermissions(ValidUserId)).Returns(ValidPermissionList);
var authClient = new Mock<AuthClient>();
// I want to use mock dependencies here to test flow against mock data
User user = authClient.Login(UserName, Password);
Assert.IsNotNull(user);
}
}
有什么想法哪里出問題了嗎?
Moq允許您測試依賴於其他類/對象的類(在許多其他事情中)。 注意:Moq不是IOC容器。
在您的AuthClient類中,您不允許給它任何依賴關系,而是實例化了它自己的實例,例如
IAuthenticationService authenticationService = new AuthenticationService();
相反,您需要在AuthClient類上定義一個構造函數,該結構接受兩個對象(它應該依賴於該對象),還有其他“注入”依賴關系的方法,但是現在我們將使用構造函數注入(很好的示例)
例如
public class AuthClient
{
string Dictionary<string, IList<UserPermissions> _userPermissions;
private IAuthenticationService _authenticationService;
private IAuthorizationService _authorizationService;
public AuthClient(IAuthenticationService authenticationService, IAuthorizationService authorizationService)
{
_authenticationService = authenticationService;
_authorizationService = authorizationService;
}
User Login(string username, string password)
{
User user = _authenticationService.Login(username, password);
var permissions = _authorizationService.GetPermissions(user);
_userPermissions.Add(user.Username, permissions);
return user;
}
}
現在,每次要使用此類時,都必須告訴它應使用哪種授權服務和身份驗證服務。 您已經將AuthClient與特定的實現(現在非常可測試且可重用)解耦了(如果您要創建一個新的AuthenticationService,該功能與舊的完全不同,則只需編寫一個實現IAuthenticationService的類!)
現在,每次要使用AuthClient時,都必須包括AuthClient的依賴項(將其交給其構造函數)。 您應該閱讀有關依賴注入和IOC(控制反轉)的更多信息(這是一個非常大的主題,可以通過多種不同的方式來完成相同的事情),google是您的朋友。
現在,測試類應如下所示:
public class UnitTestClass
{
public string UserName {get;set;}
public string Password {get;set;}
[TestInitialize]
public void Setup()
{
UserName = "test";
Password = "test123";
}
[TestMethod]
public void When_ValidUserCredentials_Expect_UserIsNotNull()
{
var mockAuthenticationService = new Mock<IAuthenticateService>();
mockAuthenticationService.Setup(m => m.Login(ValidUserName, ValidPassword)).Returns(ValidUserDto);
var mockAuthorizationService = new Mock<IAuthorizeService>();
mockAuthorizationService.Setup(m => m.GetAllPermissions(ValidUserId)).Returns(ValidPermissionList);
// Here we are "injecting" the dependencies into the AuthClient
var authClient = new AuthClient(mockAuthenticationService.Object, mockAuthorizationService.Object);
// This service call will now use the supplied (mocked) services above
User user = authClient.Login(UserName, Password);
Assert.IsNotNull(user);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.