Sidharth Nayyar
Sidharth Nayyar

Reputation: 43

Moq mock generic and expression function

I'm getting some issues while I try to mock a delegate. What I have so far is:

Interface ISpecification:

TResult FindOne<T, TResult>(
    ISpecification<T> criteria, Expression<Func<T, TResult>> property)
    where T : class;

Implementation Specification:

public virtual TResult FindOne<T, TResult>(
    ISpecification<T> criteria, Expression<Func<T, TResult>> property)
    where T : class
{
      return criteria.SatisfyingItemFrom(GetQuery<T>(), property);
}

Call that I'm trying to mock:

var spec = new MySpecification(Id, s).OrderByDescending(x => x.Code).Take(1);
string LineId = _Repository.FindOne(spec, line => line.Id);

The mock that I have so far (that is not working):

_warehouseRepositoryMock
.Setup(x => x.FindOne(It.IsAny<MySpecification>(),
    It.IsAny<Expression<Func<Line, object>>>()))
.Returns(TestLine.Id);

The error that I'm getting is:

Moq.MockException : IGenericRepository.FindOne(Specification`1[Line], line => line.Id) invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.

But I'm unsure how to send line => line.Id into my mock.

Upvotes: 2

Views: 1249

Answers (1)

abto
abto

Reputation: 1628

As far as I can tell the It.IsAny<T>() clauses have to match the declaration.

Using

TResult FindOne<T, TResult>(
    ISpecification<T> criteria,
    Expression<Func<T, TResult>> property) where T : class;

with T as Line and TResult as string it gives you the equivalent of

string FindOne(
    ISpecification<Line> criteria,
    Expression<Func<Line, string>> property);

and the setup therefore has to be

_warehouseRepositoryMock.Setup(x => x.FindOne(
    It.IsAny<ISpecification<Line>>(),
    It.IsAny<Expression<Func<Line, string>>>())).Returns(TestLine.Id);

If you want to restrict criteriato any type or subtype of MySpecification you can setup with It.Is<T>():

_warehouseRepositoryMock.Setup(x => x.FindOne(
    It.Is<ISpecification<Line>>(s => s is MySpecification),
    It.IsAny<Expression<Func<Line, string>>>())).Returns(TestLine.Id);

Upvotes: 1

Related Questions