1

Using Moq. I have a repository with the following interface:

public virtual IEnumerable<TEntity> GetBySpec(ISpecification<TEntity> specification, params string[] includes)
{
        IQueryable<TEntity> query = includes.Aggregate<string, IQueryable<TEntity>>(_dbSetQuery, (current, include) => current.Include(include));

        return query.Where(specification.SatisfiedBy())
                                 .AsEnumerable<TEntity>();
}

In this case, i'm using a DirectSpecification:

public sealed class DirectSpecification<TEntity> : Specification<TEntity>
{
    Expression<Func<TEntity, bool>> _MatchingCriteria;

    public DirectSpecification(Expression<Func<TEntity, bool>> matchingCriteria)
    {
        _MatchingCriteria = matchingCriteria;
    }

    public override Expression<Func<TEntity, bool>> SatisfiedBy()
    {
        return _MatchingCriteria;
    }
}

In my actual code i'm calling

var recentlyChanged = _vwPersonRepository.GetBySpec(
               new DirectSpecification<vwPerson>(person =>
                   person.ModifiedDate > modifiedFromDay &&
                   person.ModifiedDate < modifiedTo));

var recentlyCreated = _vwPersonRepository.GetBySpec(
               new DirectSpecification<vwPerson>(person =>
                   person.CreatedDate > createdFromDay &&
                   person.CreatedDate < createdTo));

Edit: As suggested by duplicate, I've tried this:

        Container.GetMock<IvwPersonRepository>()
            .Setup(p => p.GetBySpec(It.IsAny<ISpecification<vwPerson>>()))                        
            .Returns((Expression<Func<vwPerson, bool>> predicate) => 
              items.Where(predicate));

I get a

Exception thrown: 'System.Reflection.TargetParameterCountException' in mscorlib.dll

Additional information: Parameter count mismatch.

My question is complicated by having the ISpecification parameter, how can I get the correct parameters so I can work with the predicate?

Edit 2: Thanks to Patrick, here is the solution:

        Container.GetMock<IvwPersonRepository>()
            .Setup(p => p.GetBySpec(It.IsAny<ISpecification<vwPerson>>(), It.IsAny<string[]>()))                        
            .Returns((ISpecification<vwPerson> specification, string[] includes) => 
              items.Where(predicate));

They key was to include the string[] includes, even though I don't pass it as a parameter the reflection finds it and expects it to be there.

Brilliant!

user917170
  • 1,591
  • 15
  • 28
  • 1
    possible duplicate of [Moq'ing methods where Expression> are passed in as parameters](http://stackoverflow.com/questions/5196669/moqing-methods-where-expressionfunct-bool-are-passed-in-as-parameters) – Patrick Quirk Aug 31 '15 at 11:44
  • @Patrick: Thanks, very close but I have an extra step with the `ISpecification`, I've updated the question – user917170 Aug 31 '15 at 23:43

1 Answers1

2

The Setup call in your edit is wrong, it should be:

Container.GetMock<IvwPersonRepository>()
         .Setup(p => p.GetBySpec(It.IsAny<ISpecification<vwPerson>>()))
         .Returns((ISpecification<vwPerson> specification) => /* TODO */);

(This is because the parameters passed to Returns are the parameters passed to the function being setup, which in this case is GetBySpec.)

I believe (based on what you posted) you could just do this:

Container.GetMock<IvwPersonRepository>()
         .Setup(p => p.GetBySpec(It.IsAny<ISpecification<vwPerson>>()))
         .Returns((ISpecification<vwPerson> specification) => items.Where(specification.SatisfiedBy()));

However, you might see some benefit by using a factory to create your specifications so that you can mock them to avoid relying on their implementation (in the call to SatisfiedBy above).

Patrick Quirk
  • 23,334
  • 2
  • 57
  • 88
  • I copied exactly what you have, that looks like it would work but I still get the same exception, `System.Reflection.TargetParameterCountException`, `Parameter count mismatch`. I believe the issue now is that there are two parameters to `GetBySpec`, the spec and `params string[] includes`. Even though my call doesn't use it something about the reflection does. How would I include the includes in the setup? Thanks! – user917170 Sep 01 '15 at 22:51
  • Ah I didn't see that parameter in your sample (had to scroll horizontally). Glad to see you got to the solution! – Patrick Quirk Sep 02 '15 at 12:04