替换 IDBSet/IQueryable 的 Any() 调用



我正在尝试用 NSubstitute 替换IDBSet<T>的调用Any(),但测试失败并出现ArgumentNullException

测试

名称:测试方法 1 测试 全名:Clientmanagement.Tests.UnitTest1.TestMethod1 测试 来源: c:\develop\Clientmanagement\Clientmanagement.Tests\UnitTest1.cs :第 12 行测试结果:测试失败 持续时间:0:00:00.3701927

结果消息:测试方法 Clientmanagement.Tests.UnitTest1.TestMethod1 抛出 exception: System.ArgumentNullException: 值不能为空。 参数名称:参数 结果堆栈跟踪:at System.Linq.Expressions.Expression.RequiresCanRead(Expression 表达式,字符串参数名称) at System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arg, ParameterInfo pi)
at System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase 方法, 表达式类型 nodeKind, 只读集合 1& arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable
1 个参数) at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo 方法, 表达式[] 参数) at System.Linq.Queryable.Any[TSource](IQueryable 1 source, Expression 1 谓词)在 Clientmanagement.Tests.UnitTest1.TestMethod1() in c:\develop\Clientmanagement\Clientmanagement.Tests\UnitTest1.cs:line 19

这是我的测试方法的样子

public void EnsureThatIdentifierIsUnique() {
  IClientContext context = Substitute.For<IClientContext>();
  IDbSet<Client> clients = Substitute.For<IDbSet<Client>>();
  context.Clients.Returns(clients);
  clients.Any(p=>p.Identifier == "Test").Returns(true);  // this line throws the exception
  ClientService service = new ClientService(context);
  service.CreateClient("Test");
}

现在我的问题是是否可以用NSubstitute代替IQueryable方法?我的测试方法设置有误吗?

现在我的问题是,是否有可能用 NSubstiente 代替 IQueryable 的方法?

Any不是IQueryable的方法。它是一种扩展方法 - 一种静态方法,就像它是实例方法一样调用。因此,除非 NSubstitute 能够以某种方式模拟静态方法(如 Typemock Sollator 所做的),否则您将遇到问题。

一个真正智能的面向 LINQ 的模拟系统基本上可以Queryable提供虚假信息,并在生产代码提供类似的表达式树时响应类似的表达式树 - 但它将非常脆弱。如果可能的话,最好使用内存数据库。

通常,如果另一个序列是等效的,则不应依赖生产代码进行精确的调用序列。例如,将生产代码编写

clients.Where(p=>p.Identifier == "Test").Any()

它的可读性不高,但它基本上等同于使用谓词调用Any。您的测试应该能够实现生产代码所实现的目标,而不是实现它所需的确切步骤。

最新更新