簡體   English   中英

如何使用在方法中具有依賴項的moq對單元進行單元測試?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM