【问题标题】:Testing authenticate methods测试验证方法
【发布时间】:2019-07-05 10:25:18
【问题描述】:

我目前正在尝试学习单元测试,并且我已经在 ASP.NET Core 中创建了项目,因此我可以在真实示例中学习测试。我想在 API Controller 中测试验证方法的快乐路径,所以它会返回 OkObjectResult。

到目前为止我所拥有的。

我想测试的控制器方法

        [AllowAnonymous]
        [HttpPost("authenticate")]
        public IActionResult Authenticate([FromBody]User userParam)
        {
            var user = _userService.Authenticate(userParam.Nickname, 
            userParam.Password).Result;

            if(user == null)
            {
                return BadRequest(
                  new { message = "Username or password is incorrect " }
                );
            }

            return Ok(user);
        }

在实现 IUserService 的类中验证方法:

public async Task<User> Authenticate(string nickname, string password)
        {
            var user = _repository.User.GetAllUsersAsync().Result.SingleOrDefault(u => u.Nickname == nickname && u.Password == password);

            if(user == null)
            {
                return null;
            }

            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
            var tokenDescription = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, user.UserId.ToString())
                }),
                Expires = DateTime.UtcNow.AddDays(7),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };

            var token = tokenHandler.CreateToken(tokenDescription);
            user.Token = tokenHandler.WriteToken(token);

            try
            {
                await _repository.User.UpdateUserAsync(user);

                user.Password = null;

                return user;
            }
            catch (Exception e)
            {
                return user;
            }

        }

还有我的单元测试:

        [Fact]
        public void Authenticate_WhenCalled_ReturnsOk()
        {
            //Arrange
            var mockService = new Mock<IUserService>();
            var user = new User()
            {
                UserId = 4,
                IsAdmin = true,
                Token = "12983912803981",
                IsLogged = true,
                MessagesSent = null,
                MessagesReceived = null,
                Nickname = "test3",
                Password = "Str0ngP@ssword123",
                UserChannels = null
            };

            var controller = new UsersController(_repository, _logger, mockService.Object);

            //Act
            var result = controller.Authenticate(user);

            //Assert
            var okResult = result.Should().BeOfType<OkObjectResult>();
        }

但是,单元测试返回的是 BadRequest,而不是预期的 OkObjectResult。 这可能意味着用户实际上是 null 并且它正在抛出一个 BadRequest。我应该模拟 Repository 而不是 IUserService 吗?

【问题讨论】:

  • 你应该设置方法 Authenticate of your mock of _userService
  • 这与您的问题无关,但您的代码似乎暗示您的应用程序正在以明文形式存储密码。请,请,请不要永远在现实生活中的应用程序中这样做。你不想得到written up by Troy Hunt

标签: c# unit-testing asp.net-core jwt


【解决方案1】:

实际上,你做得很好,并且完美地完成了所有事情(实际上使用 AAA 的开发人员太少,这很可悲),但请记住 Mock 默认返回 default(T) 值。因此,您的 Authenticate 方法被模拟并返回 default(User),即 null。 只需让它返回您的存根用户:

 var mockService = new Mock<IUserService>();
 var user = new User()
        {
            UserId = 4,
            IsAdmin = true,
            Token = "12983912803981",
            IsLogged = true,
            MessagesSent = null,
            MessagesReceived = null,
            Nickname = "test3",
            Password = "Str0ngP@ssword123",
            UserChannels = null
        };
 mockService.Setup(x=> x.Authenticate(It.IsAny(), It.IsAny())).Returns(user);

或@xander提出的更多严格版本:

 mockService.Setup(x=> x.Authenticate("test3", "Str0ngP@ssword123")).Returns(user);

它还会检查您是否实际使用了传入的用户值,而不仅仅是盲目地返回 Ok()。

【讨论】:

  • 这可以通过使Setup 更具体:mockService.Setup(x=&gt; x.Authenticate("test3", "Str0ngP@ssword123")).Returns(user); 来稍微改进。使用真实值而不是 It.IsAny() 需要将 正确 值传递给模拟。
  • 谢谢,我会将您的建议添加到答案中。
  • 谢谢你们。事实就是这样。奇迹般有效! :)
猜你喜欢
  • 1970-01-01
  • 2016-04-18
  • 2014-12-01
  • 2015-05-31
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多