使用 NUnit 和 Moq 返回 Null 的单元测试异步控制器方法

Unit Testing Async Controller Method Returning Null with NUnit and Moq

我有一个 .NET Core API Framework 6.0,我正在使用 NUnit Framework 编写测试异步控制器方法我得到控制器身份验证方法返回的空值。当我从 Postman 打一个类似的电话时,有回应。我假设我的最小起订量遗漏了一些东西,但我已经按照文档进行操作,但无法找出问题所在。

//User Controller
    private readonly IUserService _userService;

    public UserController(IUserService userService)
    {
        _userService = userService;
    }

    [AllowAnonymous]
    [HttpPost("authenticate")]
    public async Task<IActionResult> Authenticate([FromBody] UserRequest userRequest)
    {
        try
        {
            var response = await _userService.Authenticate(userRequest); //Authenticate method is not being called, response is NULL here
            return Ok(new ApiResponse<UserResponse>().Success(response));
        }
        catch (Exception ex)
        {
            return betServerError(ex);
        }
    }

A​​uthenticate方法如下,第1行断点未命中

public async Task<UserResponse> Authenticate(UserRequest userRequest)
    {
        var user = _context.Users.Where(x => x.Email == userRequest.Email).FirstOrDefault(); //Breakpoint here is not being hit
        bool valid = false;

        if (user == null)
            throw new HttpException(HttpStatusCode.Unauthorized, "Username or password incorrect");

        //Other code ......
        
     return new UserResponse
        {
            Id = user.Id,
            Email = user.Email,
            Token = tokenString
        };
    }

UserTest.cs 看起来如下:

Mock<IUserService> UserServiceMock = new Mock<IUserService>();

    [SetUp]
    public void Setup()
    {

    }
    [Test]
    public async Task should_Login()
    {
        //Arrange
        var user = new UserResponse
        {
            Id = 1,
            Email = "username@gmail.com",
            Token = "TEST_TOKEN"
        };
        UserServiceMock.Setup(x => x.Authenticate(new UserRequest { Email = "username@gmail.com", Password = "password" }))
            .Returns(Task.Run(() => user));
        var UserController = new UserController(UserServiceMock.Object);

        //Act
        var result = await UserController.Authenticate(new UserRequest { Email = "username@gmail.com", Password = "password1" }); //result here doesnot contain the response I expect, it has a null object
        
        //Assert
        Assert.IsNotNull(result);
        Assert.AreEqual(HttpStatusCode.OK, GetHttpStatusCode(result));
    }

您传递给 AuthenticateUserRequest 实例与您设置模拟所期望的实例不同。因此,由于输入不匹配,模拟不会执行,默认模拟行为将接管。

要么删除模拟条件(即使用 It.IsAny<UserRequest>()),要么将相同的实例传递给模拟和控制器方法。