我使用Moq来模拟一个方法调用,我想模拟一个null响应。Login
方法返回一个LoginResult
类型。
我的登录界面:
public async Task<LoginResult> Login(string userPin)
我的单元测试模拟:
var credentialsService = new Mock<ICredentialsService>();
credentialsService.Setup(x => x.Login("1234")).ReturnsAsync((LoginResult)null);
有了上面的模拟,我收到了以下警告:
警告1:
警告CS8600正在将null文字或可能的null值转换为不可为null的类型
警告2:
类型为"ISetup<ICredentialsService,任务>'不能用于类型为"IReturns<ICredentialsService,任务<登录结果>gt;'在"IReturnsResult ReturnsExtensions"中。ReturnsAsync<ICredentialsService,登录结果>(IReturns<ICredentialsService,Task<LoginResult?>>mock,LoginResults?value(',这是由于引用类型的可空性存在差异。
如何解决这两个警告?
您知道如果您不设置mock,那么它将默认返回null
吗?
这是由于Mock<T>()
构造函数使用了MockBehavior.Default
值。
MockBehavior
可以具有以下值:
Strict
:每当在没有匹配配置的情况下调用方法或属性时,都会引发异常Loose
:Moq接受所有调用并尝试创建一个有效的返回值Default
:与Loose
相同
因此,如果使用MockBehavior.Strict
定义mock,那么如果没有Setup
-Returns
语句,则会收到异常。但是因为默认行为是Loose
,所以不需要执行任何Setup
-Returns
调用。
显示的示例使用LoginResult
,但警告显示预期返回类型的实际类型为LoginResult?
。这就是转换警告的原因。
credentialsService.Setup(x => x.Login("1234")).ReturnsAsync((LoginResult?)null);
如果使用ReturnsAsync
导致问题,请将Returns
与手动创建的Task
一起使用
credentialsService
.Setup(x => x.Login(It.IsAny<string>()))
.Returns(s => Task.FromResult<LoginResult?>((LoginResult?)null));