简体   繁体   English

ASP.NET MVC 5 - 仅使用身份的单元测试服务

[英]ASP.NET MVC 5 - Unit Testing Service that uses only Identity

I have this class, that, actually, only does operations on top of ASP.NET Identity.我有这个 class,实际上,它只在 ASP.NET 身份之上进行操作。

 public class AuthenticationService : IAuthenticationService
    {
        private readonly ApplicationSignInManager _signInManager;
        private readonly ApplicationUserManager _userManager;
        private readonly IAuthenticationManager _authManager;
        private readonly HttpContextBase _context;

        public AuthenticationService(
            ApplicationSignInManager signInManager, 
            ApplicationUserManager userManager, 
            IAuthenticationManager authManager,
            HttpContextBase context)
        {
            _signInManager = signInManager;
            _userManager = userManager;
            _authManager = authManager;
            _context = context;
        }

        public async Task<SignInStatus> SignIn(string email, string password)
        {
            var result = await _signInManager.PasswordSignInAsync(email, password, true, shouldLockout: false);
            return result;
        }

        public async Task<IdentityResult> Register(string email, string password)
        {
            var user = new AppUser
            {
                UserName = email,
                Email = email,
            };

            var result = await _userManager.CreateAsync(user, password);

            return result;
        }

        public void SignOut()
        {
            _authManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        }

        public async Task<IdentityResult> ForgotPassword(string email, string newPassword)
        {
            var user = await _userManager.FindByEmailAsync(email);
            string resetToken = await _userManager.GeneratePasswordResetTokenAsync(user.Id);
            var result = await _userManager.ResetPasswordAsync(user.Id, resetToken, newPassword);

            return result;
        }

        public async Task<AppUser> GetUserByEmail(string email)
        {
            var user = await _userManager.FindByEmailAsync(email);
            return user;
        }

        public string GetLoggedInUserId()
        {
            if(_context.User.Identity.IsAuthenticated)
            {
                return _context.User.Identity.GetUserId();
            }
            return string.Empty;
        }
    }

I don't know if I'm injecting the right dependencies.我不知道我是否注入了正确的依赖项。 But my question is:但我的问题是:

In a class like this one, what would make sense to unit test?在像这样的 class 中,单元测试有什么意义? Since most methods call methods related to Identity and only return the result.由于大多数方法调用与 Identity 相关的方法并且只返回结果。

The only test that it seems right to do is what happens when I try to get the ID of a user if no user is authenticated.唯一似乎正确的测试是,如果没有用户通过身份验证,当我尝试获取用户的 ID 时会发生什么。

In almost any class you can test, assuming that it's a unit test of one entity under test and all internal dependencies(like ApplicationUserManager or IAuthenticationManager ) are mocked:在几乎任何 class 中,您都可以进行测试,假设它是一个被测实体的单元测试并且所有内部依赖项(如ApplicationUserManagerIAuthenticationManager )都被模拟:

  1. All internal services are called exact number of times所有内部服务被调用的确切次数
  2. The entity under test does not change arguments passed in a method, and correctly passes them into calls of internal services (like ApplicationUserManager or IAuthenticationManager )被测实体不会更改方法中传递的 arguments,并正确地将它们传递给内部服务的调用(如ApplicationUserManagerIAuthenticationManager

So, for example, you can test in SignIn that _signInManager.PasswordSignInAsync gets called exactly once and arguments are, for email and password — the same as they were passed into SignIn ;因此,例如,您可以在SignIn中测试_signInManager.PasswordSignInAsync被调用一次,并且 arguments 是,对于emailpassword - 与传递给SignIn的相同; for the third unnamed argument and shouldLockout — they are according to business logic — true and false.对于第三个未命名的参数和shouldLockout - 它们根据业务逻辑 - true 和 false。

ForgotPassword is trickier: you have data passed from _userManager.FindByEmailAsync to _userManager.GeneratePasswordResetTokenAsync and then to _userManager.ResetPasswordAsync . ForgotPassword比较棘手:您将数据从_userManager.FindByEmailAsync传递到_userManager.GeneratePasswordResetTokenAsync ,然后_userManager.ResetPasswordAsync
In this case, you don't need to test results of these three calls are correct as such thing should be tested in tests for _userManager , but you will need to test that calls to all these services are made exact number of times.在这种情况下,您不需要测试这三个调用的结果是否正确,因为应该在_userManager的测试中进行测试,但您需要测试对所有这些服务的调用是否准确执行次数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM