[英]How can I stub an interface method using Moq
有没有一种方法可以使用Moq存根方法? 我看到了很多标题相似的问题,但没有一个能真正回答我的问题。 这是给我的一个单元测试示例,我发现使用Moq进行测试非常困难。 我想做的是对EmailTasks.UserIsValidForNotice()方法进行单元测试:
public class User
{
public DateTime JoinDate { get; set; }
public bool Active { get; set; }
}
public class EmailTasks
{
IUserRepository repo;
public EmailTasks(IUserRepository repo)
{
this.repo = repo;
}
public IList<User> UserIsValidForNotice(DateTime minDate)
{
return repo.FindAll(u => u.Active && u.JoinDate > minDate);
}
}
public interface IUserRepository
{
IList<User> FindAll(Func<User, bool> q);
}
我可以像下面那样建立一个存根,然后轻松地测试查询,但是由于无法访问Mocks Return函数中的方法参数,因此无法使用Moq进行查询。
public class StubRepo : IUserRepository
{
public IList<User> PersonList { get; set; }
public IList<User> FindAll(Func<User, bool> q)
{
return PersonList.Where(q).ToList();
}
}
我知道这可能不是最好的设计,但是我只是想知道是否可以使用Moq完成。
这里的问题是您要测试什么?
IMO,您应该测试的是您是否使用正确的Func调用了存储库。 您可以按照以下步骤进行操作:
[Test]
public void UserIsValidForNotice_has_correct_expression()
{
var repoMock = new Mock<IUserRepository>();
var sut = new EmailTasks(repoMock.Object);
sut.UserIsValidForNotice(DateTime.Now);
repoMock.Verify(r => r.FindAll(It.Is<Func<User, bool>>(func => func(someUser));
}
当调用Verify方法时,您检查是否已调用存储库。 此外,您检查是否已使用Func<User, bool>
的实例(即It.Is<>
部分) It.Is<>
它。
对于It.Is<>
您可以指定一个回调函数,该回调函数将获取传递的参数,并在参数有效时返回true,否则返回false。 因此,在该回调中,您可以对已知用户执行Func
并检查其评估是否正确。
如果您仍然想将其存根并返回某些内容,则可以这样做:
repoMock.Setup(r => r.FindAll(It.IsAny<Func<User, bool>>)
.Returns<Func<User, bool>, IList<User>>(fnc => new List<User>());
如果调用Returns
的泛型重载,则最多可以指定8个类型参数。 第一个将被传递到您提供的表达式中(从实际调用中),而最后一个将确定返回类型。
var personList = new List<User>(); // set up your personList here
var repoMock = new Mock<IUserRepository>();
repoMock.Setup(repo => repo.Findall(It.IsAny<Func<User, bool>>())
.Return((Func<user, bool> q) => personList.Where(q).ToList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.