如何使用Moq构建此表达式而不会出现方法组错误?

时间:2012-12-24 19:33:19

标签: c# testing fluent-nhibernate moq mspec

我需要在给定集合上运行表达式,以确定代码中的表达式是否正确写入。为了示例,我将省略一些不必要的上下文,但如果有人需要它,只需评论,我将编辑问题并添加您需要的任何内容。

假设我有以下内容:

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&gt;)'的最佳重载方法匹配有一些无效的参数

  

参数1:无法从'方法组'转换为
  'System.Linq.Expressions.Expression&GT;'`

4 个答案:

答案 0 :(得分:14)

要修复此类错误,您需要调用该方法,而不是将其作为参数传递。只需更改您的电话:

Moq.It.IsAny<Expression<Func<SomeObject, bool>>>

为:

Moq.It.IsAny<Expression<Func<SomeObject, bool>>>()

请注意括号。

答案 1 :(得分:3)

根据this answer,您之后看起来需要(),例如It.IsAny<Expression<Func<SomeObject, bool>>>()

答案 2 :(得分:0)

上面包含了一个具体的存储库,但它从未在本规范中使用过,所以我只是为了举例而信任它。此外,规范有一个模拟的存储库和一个设置查询方法,但它永远不会执行。此规范应该测试使用存储库的具体事物。然后,您可以比较传递给查询方法的表达式。

表达式很棘手,但对于模拟更是如此。我所做的是使用Moq的验证,然后使用Moq的Moq.It.Is&lt;&gt;确保仅在表达式匹配时才传递验证。这是一个例子:

_repo.Verify(x=>x.Query(Moq.It.Is<Expression<Func<SomeObject, bool>>>(exp=>exp.Compile().Invoke(_exampleSomeObject)));

基本上,在这里,我告诉Moq,如果给定的实际表达式适用于_exampleSomeObject,则验证仅通过。

我在Iphone上打字,所以如果代码不能立即编译,我很抱歉。

只是一个建议:你的因为部分应该表达一些导致结果的行为。现在,它看起来像你的公共汽车只处理之前的结果。

答案 3 :(得分:0)

在您的设置中,您正在传递SomeObject 在你的回调中,你要求InstanceHealthReport。

即使InstanceHealthReport是SomeObject的子类,我相信它们需要在设置和回调中匹配。

希望有所帮助。

科林