我正在尝试用 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)
1 个参数) at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo 方法, 表达式[] 参数) at System.Linq.Queryable.Any[TSource](IQueryable
at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable1 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
。您的测试应该能够实现生产代码所实现的目标,而不是实现它所需的确切步骤。