And*_*rew 7 .net c# unit-testing moq verify
我有一个带有Add方法的存储库,该方法将IEnumerable作为参数:
public void Add<T>(T item) where T : class, new(){}
Run Code Online (Sandbox Code Playgroud)
在单元测试中,我想验证是否使用IEnumerable调用此方法,该IEnumerable包含与另一个IEnumerable完全相同的元素数量
[Test]
public void InvoicesAreGeneratedForAllStudents()
{
var students = StudentStub.GetStudents();
session.Setup(x => x.All<Student>()).Returns(students.AsQueryable());
service.GenerateInvoices(Payments.Jaar, DateTime.Now);
session.Verify(x => x.Add(It.Is<IEnumerable<Invoice>>(
invoices => invoices.Count() == students.Count())));
}
Run Code Online (Sandbox Code Playgroud)
单元测试结果:
Moq.MockException :
Expected invocation on the mock at least once, but was never performed:
x => x.Add<Invoice>(It.Is<IEnumerable`1>(i => i.Count<Invoice>() == 10))
No setups configured.
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
从您的代码示例中,您尚未在最小起订量上设置 x => x.Add
session.Setup(x => x.Add(It.IsAny<IEnumerable>());
Run Code Online (Sandbox Code Playgroud)
除非 x.All 的设置是 x.Add?如果是这样,您需要精确匹配验证和设置 - 一个好的方法是将其提取到返回表达式的通用方法。
编辑:添加了一个示例,我更改了 Add 的签名,因为我看不到如何传递集合。
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
Mock<Boo> moqBoo = new Mock<Boo>();
moqBoo.Setup(IEnumerableHasExpectedNumberOfElements(10));
// ACT
moqBoo.Verify(IEnumerableHasExpectedNumberOfElements(10));
}
private static Expression<Action<Boo>> IEnumerableHasExpectedNumberOfElements(int expectedNumberOfElements)
{
return b => b.Add(It.Is<IEnumerable<Invoice>>(ie => ie.Count() == expectedNumberOfElements));
}
}
public class Boo
{
public void Add<T>(IEnumerable<T> item) where T : class, new()
{
}
}
public class Invoice
{
}
Run Code Online (Sandbox Code Playgroud)
另外,调试这些东西的一个好方法是使用 MockBehavior.Strict 设置 Mock,然后调用的代码会通知您需要配置什么。