I have a .NET Core API Framework 6.0, I'm writing tests an Async Controller method using NUnit Framework I'm getting null value returned by the Controller Authentication method. When I make a similar call from Postman there is response. I assume my Moq is missing something but I have followed documentation and cannot figure out the issue.
//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);
}
}
The Authenticate method is as below, the breakpoint on Line 1 is not being hit.
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 looks as follows:
Mock<IUserService> UserServiceMock = new Mock<IUserService>();
[SetUp]
public void Setup()
{
}
[Test]
public async Task should_Login()
{
//Arrange
var user = new UserResponse
{
Id = 1,
Email = "[email protected]",
Token = "TEST_TOKEN"
};
UserServiceMock.Setup(x => x.Authenticate(new UserRequest { Email = "[email protected]", Password = "password" }))
.Returns(Task.Run(() => user));
var UserController = new UserController(UserServiceMock.Object);
//Act
var result = await UserController.Authenticate(new UserRequest { Email = "[email protected]", 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));
}
CodePudding user response:
The UserRequest
instance you're passing into Authenticate
is a different instance than what you're setting up your mock to expect. So, since the inputs don't match, the mock is not executed, and the default mock behavior takes over.
Either remove the mock conditional (i.e., use It.IsAny<UserRequest>()
), or pass the same instance to your mock and your controller method.