Reputation: 37
This is my function of a controller class, I want to test this but I didn't have any idea to know why checking the OkObject
is null. I need some advice and a way to solve this:
[HttpGet]
public async Task<IActionResult> LoginAsync(string phoneNumber, string pass)
{
User login = new User();
login.Phone = phoneNumber;
login.Password = pass;
IActionResult response = Unauthorized();
var user = await _loginService.AuthenticateUserAsync(login);
if(user != null)
{
var tokenStr = _loginService.GenerateJWT(user);
response = Ok(new { token = tokenStr });
}
return response;
}
My test function is :
[Fact]
public async Task LoginAsync_ReturnOk()
{
var mock = new Mock<ILoginService>();
var controller = new LoginController(mock.Object);
var phone = "0123456789";
var pass = "abc123";
var okResult = await controller.LoginAsync(phone, pass);
Assert.IsType<OkObjectResult>(okResult as OkObjectResult);
}
I really need help from you.
Upvotes: 2
Views: 1106
Reputation: 247333
The test is failing because the mocked dependency has not been configured to behave as expected for the current test case.
The subject under test for the stated test case needs
//...
if(user != null)
//...
to be true but the _loginService
was not configured for the test case
//...
var user = await _loginService.AuthenticateUserAsync(login);
//...
That means that the subject under test will return UnauthorizedResult
This will cause okResult as OkObjectResult
to be null
The test needs to be arranged so that the test case, when exercised, will behave as expected
[Fact]
public async Task LoginAsync_Should_Return_Ok() {
// Arrange
var mock = new Mock<ILoginService>();
var user = new UserResult(); //Or what ever the actual user type is
mock.Setup(_ => _.AuthenticateUserAsync(It.IsAny<User>()))
.ReturnsAsync(user);
string tokenStr = "some token value";
mock.Setup(_ => _.GenerateJWT(user)).Returns(tokenStr);
LoginController controller = new LoginController(mock.Object);
string phone = "0123456789";
string pass = "abc123";
//Act
IActionResult response = await controller.LoginAsync(phone, pass);
//Assert
OkObjectResult okResult = Assert.IsType<OkObjectResult>(response);
//Optional: additional assertions for this test case
dynamic value = okResult.Value;
Assert.NotNull(value);
string token = (string)value.token;
Assert.Equal(token, tokenStr);
}
And since there is also the possible outcome of having an unauthorized response, here is the other test case to cover that controller action
[Fact]
public async Task LoginAsync_Should_Return_Unauthorized() {
//Arrange
var mock = new Mock<ILoginService>();
mock.Setup(_ => _.AuthenticateUserAsync(It.IsAny<User>()))
.ReturnsAsync((UserResult)null); //Or what ever the actual user type is
LoginController controller = new LoginController(mock.Object);
string phone = "0123456789";
string pass = "abc123";
//Act
IActionResult response = await controller.LoginAsync(phone, pass);
//Assert
Assert.IsType<UnauthorizedResult>(response);
}
Upvotes: 2