I'm using Moq for mocking a method call and I want to mock a null response. The Login
method returns a LoginResult
type.
My Login interface:
public async Task<LoginResult> Login(string userPin)
My unit test mock:
var credentialsService = new Mock<ICredentialsService>();
credentialsService.Setup(x => x.Login("1234")).ReturnsAsync((LoginResult)null);
With the above mock, I receive the following warnings:
warning 1:
Warning CS8600 Converting null literal or possible null value to non-nullable type
warning 2:
Argument of type 'ISetup<ICredentialsService, Task>' cannot be used for parameter 'mock' of type 'IReturns<ICredentialsService, Task<LoginResult?>>' in 'IReturnsResult ReturnsExtensions.ReturnsAsync<ICredentialsService, LoginResult?>(IReturns<ICredentialsService, Task<LoginResult?>> mock, LoginResult? value)' due to differences in the nullability of reference types.
How can I resolve these two warnings?
CodePudding user response:
Are you aware of the fact if you don't setup your mock then it will return null
by default?
This is due to the fact that the Mock<T>()
constructor uses the MockBehavior.Default
value.
The MockBehavior
can have the following values:
Strict
: an exception is thrown whenever a method or property is invoked without a matching configurationLoose
: Moq accepts all invocations and attempts to create a valid return valueDefault
: same asLoose
So, if you would define your mock with MockBehavior.Strict
then you would receive an exception if there were no Setup
-Returns
statements. But because the default behaviour is Loose
that's why you do not need to perform any Setup
-Returns
calls.
CodePudding user response:
The shown example uses LoginResult
but the warning shows the actual type of the expected return type to be LoginResult?
. That is the cause of the conversion warning.
credentialsService.Setup(x => x.Login("1234")).ReturnsAsync((LoginResult?)null);
If using ReturnsAsync
is causing issues, use Returns
with the Task
created manually
credentialsService
.Setup(x => x.Login(It.IsAny<string>()))
.Returns(s => Task.FromResult<LoginResult?>((LoginResult?)null));