I need to run an expression on a given collection to determine if the expression in the code is written correctly. For the sake of the example, I am going to leave out some unnecessary context, but if anyone needs it, just comment and I'll edit the question and add whatever you need.

Let's say I have the following:

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);
    }
}

and I want to write a spec like the following:

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
}

However, I'm getting build errors on Moq.It.IsAny<Expression<Func<SomeObject, bool>>> saying

The best overloaded method match for 'Project.Domain.IRepository.Query(System.Linq.Expressions.Expression>)' has some invalid arguments

and

Argument 1: cannot convert from 'method group' to
'System.Linq.Expressions.Expression>'`

有帮助吗?

解决方案

To fix errors like this you need to invoke the method, not pass it as an argument. Just change your call from:

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

to:

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

Note the parentheses.

其他提示

Based on this answer, it looks like you need () afterwards, e.g. It.IsAny<Expression<Func<SomeObject, bool>>>()

In your setup you are passing SomeObject.
In your callback you are asking for InstanceHealthReport.

Even if InstanceHealthReport is a subclass of SomeObject, I believe they need to match in the setup and the callback.

Hope that helps.

Colin

You included a concrete repository above, but its never used in this spec, so I trust its just for the sake of example. Further, the spec has a mocked repository and a setup query method, but it is never executed. This spec should be testing the concrete thing that uses the repository. Then you can compare the expression that was passed in to the query method.

Expressions are tricky, but even more so with mocks. What I do is use Moq's Verify and then use Moq's Moq.It.Is<> to assure that the verify only passes if the expression matches. Here's an example:

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

Basically, here I'm telling Moq that the verify only passes if the actual expression given works on _exampleSomeObject.

I'm typing on my Iphone, so I apologize if the code doesn't compile right away.

Just a suggestion: your because section should express some action that causes a result. Right now, it looks like your because of bus only processing a result from before.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top