如何使用Moq存根接口方法
有没有办法使用Moq存根方法? 我看到了很多类似头衔的问题,但实际上没有一个回答我的问题。 这是我给出的unit testing示例,我发现使用Moq进行测试非常困难。 我想做的是unit testingEmailTasks.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 UserIsValidForNotice(DateTime minDate) { return repo.FindAll(u => u.Active && u.JoinDate > minDate); } } public interface IUserRepository { IList FindAll(Func q); }
我可以设置如下的存根,然后轻松测试查询,但我无法使用Moq,因为我无法访问Mocks Return函数中的方法参数。
public class StubRepo : IUserRepository { public IList PersonList { get; set; } public IList FindAll(Func q) { return PersonList.Where(q).ToList(); } }
我知道这可能不是最好的设计,但我只是感兴趣,如果可以使用Moq完成。
这里的问题是你在测试什么?
IMO,您应该测试的是您是否使用正确的Func调用了存储库。 你可以这样做:
[Test] public void UserIsValidForNotice_has_correct_expression() { var repoMock = new Mock(); var sut = new EmailTasks(repoMock.Object); sut.UserIsValidForNotice(DateTime.Now); repoMock.Verify(r => r.FindAll(It.Is>(func => func(someUser)); }
调用Verify方法时,将检查是否已调用存储库。 此外,您检查是否已使用Func
的实例调用它(即It.Is<>
部分。
对于It.Is<>
您可以指定回调将获取传递的参数,并在参数有效时返回true,否则返回false。 因此,在该回调中,您可以对已知用户执行Func
并检查它是否正确评估。
如果你仍然希望将它存根并返回一些东西,你可以这样做:
repoMock.Setup(r => r.FindAll(It.IsAny>) .Returns, IList>(fnc => new List ());
如果调用Returns
的generics重载,则最多可以指定8个类型参数。 第一个将传递给您提供的表达式(来自实际调用),而最后一个确定返回类型。
var personList = new List(); // set up your personList here var repoMock = new Mock(); repoMock.Setup(repo => repo.Findall(It.IsAny>()) .Return((Func q) => personList.Where(q).ToList());