我需要在给定集合上运行表达式,以确定代码中的表达式是否正确编写。为了这个例子,我将省略一些不必要的上下文,但如果有人需要,请评论,我会编辑问题并添加您需要的任何内容。
假设我有以下内容:
public interface IRepository
{
IQueryable<T> Query<T>(Expression<Func<T, bool>> expression);
}
public class Repository : IRepository
{
public IQueryable<T> Query<T>(Expression<Func<T, bool>> expression)
{
return _session.Query<T>(expression);
}
}
和我想写一个规范如下:
internal class when_executing_some_query : given_some_repository_context
{
Establish context = () =>
{
IQueryable<SomeObject> objects = new List<SomeObject>
{
SomeObject1,
SomeObject2,
SomeObject3,
}.AsQueryable();
_expectedList = new List<SomeObject>
{
SomeObject1,
SomeObject2,
};
MockedRepository.Setup(x => x.Query<SomeObject>(Moq.It.IsAny<Expression<Func<SomeObject, bool>>>)
.Callback<Expression<Func<SomeObject, bool>>>(expression => _actualExpression = expression);
}
Because of = () => _actualList = objects.Select(_actualExpression).ToList();
It should_execute_on_queryable_and_return_the_expected_items = () => //compare _expectedList with _actualList
}
然而,我得到构建错误的Moq.It.IsAny<Expression<Func<SomeObject, bool>>>
说
最好的重载方法匹配'Project.Domain.IRepository.Query(System.Linq.Expressions.Expression>)'有一些无效的参数
和
参数1:不能从'method group'转换为
"System.Linq.Expressions.Expression>"
要修复这样的错误,您需要调用该方法,而不是将其作为参数传递。请更改您的呼叫:
Moq.It.IsAny<Expression<Func<SomeObject, bool>>>
:
Moq.It.IsAny<Expression<Func<SomeObject, bool>>>()
根据这个答案,看起来您之后需要()
,例如It.IsAny<Expression<Func<SomeObject, bool>>>()
在你的设置中,你正在传递SomeObject。
在你的回调中,你正在请求InstanceHealthReport。
即使InstanceHealthReport是SomeObject的子类,我认为它们需要在设置和回调中匹配。
希望对你有帮助。
科林您在上面包含了一个具体的存储库,但在本规范中从未使用过它,所以我相信它只是为了示例。此外,该规范有一个模拟存储库和一个设置查询方法,但它永远不会被执行。该规范应该测试使用存储库的具体事物。然后可以比较传递给查询方法的表达式。
表达式很棘手,但对于mock来说更是如此。我所做的是使用Moq的验证,然后使用Moq的Moq. it . is<>来确保只有在表达式匹配时验证才通过。下面是一个例子:
_repo.Verify(x=>x.Query(Moq.It.Is<Expression<Func<SomeObject, bool>>>(exp=>exp.Compile().Invoke(_exampleSomeObject)));
基本上,我在这里告诉Moq,只有当给定的实际表达式对_exampleSomeObject有效时,验证才会通过。
我正在我的Iphone上打字,所以如果代码不能立即编译,我很抱歉。
只是一个建议:你的because部分应该表达一些导致结果的动作。现在,看起来您的because of总线只处理之前的结果。