Verify method call with Lambda expression - Moq

Viewed 14594

I have a Unit of Work implementation with, among others, the following method:

T Single<T>(Expression<Func<T, bool>> expression) where T : class, new();

and I call it, for instance, like this:

var person = _uow.Single<Person>(p => p.FirstName == "Sergi");

How can I verify that the Single method has been called with an argument of FirstName == "Sergi"?

I've tried the following, but to no avail:

// direct approach 
session.Verify(x => x.Single<Person>(p => p.FirstName == "Sergi"));

// comparing expressions
Expression<Func<Person, bool>> expression = p => p.FirstName == "Sergi");

session.Verify(x => x
    .Single(It.Is<Expression<Func<Person, bool>>>(e => e == expression));

They all result in the folowing error:

Expected invocation on the mock at least once, but was never performed

Any ideas on how that can be done? I'm using the latest Moq from NuGet, version 4.0.10827.0

UPDATE: A Specific example

What I'm seeing is that whenever I use string literals inside the lambda, Verify works. As soon as I'm comparing variables it fails. Case in point:

// the verify
someService.GetFromType(QuestionnaireType.Objective)

session.Verify(x => x.Single<Questionnaire>(q => 
    q.Type == QuestionnaireType.Objective));


// QuestionnaireType.Objective is just a constant:
const string Objective = "objective";


// the method where it's called (FAILS):
public Questionnaire GetFromType(string type)
{
    // this will fail the Verify
    var questionnaire = _session
        .Single<Questionnaire>(q => q.Type == type);
}

// the method where it's called (PASSES):
public Questionnaire GetFromType(string type)
{
    // this will pass the Verify
    var questionnaire = _session
        .Single<Questionnaire>(q => q.Type == QuestionnaireType.Objective);
}

How come the Verify fails as soon as I use the method parameter in the lambda expression?

What would be the proper way to write this test?

2 Answers
Related