替换IDBSet / IQueryable的Any()调用

时间:2013-09-12 06:37:43

标签: c# linq expression iqueryable nsubstitute

我尝试用{NSOstitute'代替Any()的{​​{1}},但测试失败了IDBSet<T>

  

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

     

结果消息:测试方法   Clientmanagement.Tests.UnitTest1.TestMethod1扔了   exception:System.ArgumentNullException:Value不能为null。   参数名称:参数结果StackTrace:at   System.Linq.Expressions.Expression.RequiresCanRead(表达式   表达式,字符串paramName)at   System.Linq.Expressions.Expression.ValidateOneArgument(MethodBase   方法,ExpressionType nodeKind,Expression arg,ParameterInfo pi)
  在System.Linq.Expressions.Expression.ValidateArgumentTypes(MethodBase   方法,ExpressionType nodeKind,ReadOnlyCollection ArgumentNullException 1个参数)at   System.Linq.Expressions.Expression.Call(表达式实例,   MethodInfo方法,Expression [] arguments)at   System.Linq.Queryable.Any [TSource](IQueryable的1& arguments)
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable
1   谓词)   Clientmanagement.Tests.UnitTest1.TestMethod1()in   C:\开发\ Clientmanagement \ Clientmanagement.Tests \的UnitTest1.cs:行   19

以下是我的Test方法的样子

1 source, Expression

现在我的问题是,是否有可能将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?我的测试方法设置错了吗?

1 个答案:

答案 0 :(得分:1)

  

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

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

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

一般情况下,如果另一个序列是等效的,那么您不应该依赖生产代码来制作一个精确的调用序列。例如,您的生产代码将合理写为

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

它不具有可读性,但它基本上等同于使用谓词调用Any。您的测试应该能够生成代码,而不是完全实现它所需的步骤。