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));
