当进行单元测试时,我该如何模拟异步方法返回null?

37

通常我这样嘲笑我的代码库:

var repository = new Mock<ISRepository>();
repository.Setup(r => r.GetMemberAsync(email))
    .Returns(Task.FromResult(new Member
    {
        FirstName = firstName,
        LastName = lastName
    }));

但是,在我的代码中,我检查成员是否不存在,即GetMemberAsync返回null。我该如何模拟它?

我尝试过:

var repository = new Mock<ISRepository>();
repository.Setup(r => r.GetMemberAsync(email))
    .Returns(Task.FromResult<object>(null));

但我得到了一个编译错误。

3个回答

77

你之所以收到编译器错误信息,是因为你返回了一个与异步方法的返回类型不匹配的任务。你应该返回 Task<Member> 而不仅仅是 Task<object>

repository.Setup(r => r.GetMemberAsync(email)).Returns(Task.FromResult<Member>(null));

3
或者,您可以将 null 转换为所需的类型 - Task.FromResult((Member)null) (在 FromResult 案例中并不完全有用,但当类型较为复杂时可能会很方便)。 - Alexei Levenkov
非常感谢,它起作用了......repository.Setup(r => r.GetMemberAsync(email)).Returns(Task.FromResult<MyClass>(null)); - Vaibhav.Inspired

24

也可以在不使用Task类的情况下返回结果。

repository
    .Setup(r => r.GetMemberAsync(email))
    .ReturnsAsync((Member)null);

使用Async并确保将NULL进行类型转换; - FlyingV

3

虽然这是一个旧问题,但我认为还有更简洁的方法:

假设你的对象的默认值是 null,你也可以使用以下方法:

default(<insert object type here>)

e.g.

default(Member)
default(List<string>)
etc.

完整示例:
var myRepo = new Mock<IMyRepo>();
myRepo 
    .Setup(p => p.GetAsync("name"))
    .ReturnsAsync(default(List<string>));

这比仅仅返回 null 更不明确且冗长。 - Olivier Giniaux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接