I am trying to learn MOQ as well as unit testing with xUnit at the same time.
I have an Authentication logic class with a few methods. They all make use of an AuthenticationDataAccessor. I am trying to mock out that accessor to retain unit test isolation to the logic only.
I am trying to unit test the logic of two methods within my logic class.
RegisterAsync and AuthenticateAsync
private void SetupMocks()
{
// Mock the data accessor.
var _mockedDataAccessor = new Mock<IAuthenticationData>();
// Moke the call that will go to the mocked data accessor.
var _mockedAuthenticationRequest = new AuthenticationRequest { Username = It.IsAny<string>(), Password = It.IsAny<string>() };
var _mockedRegistrationRequest = new RegistrationRequest { Email = It.IsAny<string>(), Password = It.IsAny<string>(), Firstname = It.IsAny<string>(), Surname = It.IsAny<string>() };
// Setup the accessor.
_mockedDataAccessor
.Setup(x => x
.AuthenticateAsync(_mockedAuthenticationRequest))
.ReturnsAsync(
new SharedLib.Responses.UserResponse
{
ResponseState = new SharedLib.Responses.ResponseState
{
Description = "Moq description",
IsSuccess = true,
ResponseCode = ResponseCode.OK,
SystemError = false
}
});
_mockedDataAccessor
.Setup(x => x
.RegisterAsync(_mockedRegistrationRequest))
.ReturnsAsync(
new SharedLib.Responses.RegistrationResponse
{
ResponseState = new SharedLib.Responses.ResponseState
{
Description = "Moq description",
IsSuccess = true,
ResponseCode = ResponseCode.OK,
SystemError = false
}
});
// Create the logic reference based on the mocked data accessor
_logic = new AuthenticationLogic(_mockedDataAccessor.Object);
}
So, I have two setup calls. One for data accessor method I am mocking out.
However, when I execute my unit test:
[Fact]
public async void RegisterWithValidDetailsReturnsSuccess()
{
SetupMocks();
var result = await _logic.RegisterAsync(new RegistrationRequest
{
Email = "a.valid@email.com",
Firstname = "ValidFirstname",
Password = "AString@Password123",
Surname = "AValid Surname",
TimezoneId = 1
});
Assert.Equal(ResponseCode.OK, result.ResponseState.ResponseCode);
}
result
is always null. I'd expect it to bewhat ever I set in my setup above.
Note that a test that uses my Authenticate mock, works. It seems the 2nd mock fails.
[Fact]
public async void BlankUsernameReturnsError()
{
SetupMocks();
var result = await _logic.AuthenticateAsync(new AuthenticationRequest
{
Password = "AFantastic123Password@",
Username = "",
});
Assert.Equal(ResponseCode.LoginInvalidCredentials, result.ResponseState.ResponseCode);
}
That works.
Maybe you can't have two 'setup' on the same mocked class? And I need to have a specific setup per test? Maybe the private void Setup()
is a problem/bad idea?