Прямой подход у меня прекрасно работает:
// direct approach
session.Verify(x => x.Single<Person>(p => p.FirstName == "Sergi"));
Объект выражения не возвращает true для эквивалентных выражений, поэтому произойдет сбой:
// 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));
Чтобы понять почему, запустите следующий тест NUnit:
[Test]
public void OperatorEqualEqualVerification()
{
Expression<Func<Person, bool>> expr1 = p => p.FirstName == "Sergi";
Expression<Func<Person, bool>> expr2 = p => p.FirstName == "Sergi";
Assert.IsTrue(expr1.ToString() == expr2.ToString());
Assert.IsFalse(expr1.Equals(expr2));
Assert.IsFalse(expr1 == expr2);
Assert.IsFalse(expr1.Body == expr2.Body);
Assert.IsFalse(expr1.Body.Equals(expr2.Body));
}
И, как показывает приведенный выше тест, сравнение по телу выражения также не удастся, но сравнение строк работает, так что это также работает:
// even their string representations!
session.Verify(x => x
.Single(It.Is<Expression<Func<Person, bool>>>(e =>
e.ToString() == expression.ToString()));
А вот еще один стиль тестирования, который вы можете добавить к арсеналу, который также работает:
[Test]
public void CallbackVerification()
{
Expression<Func<Person, bool>> actualExpression = null;
var mockUow = new Mock<IUnitOfWork>();
mockUow
.Setup(u => u.Single<Person>(It.IsAny<Expression<Func<Person, bool>>>()))
.Callback( (Expression<Func<Person,bool>> x) => actualExpression = x);
var uow = mockUow.Object;
uow.Single<Person>(p => p.FirstName == "Sergi");
Expression<Func<Person, bool>> expectedExpression = p => p.FirstName == "Sergi";
Assert.AreEqual(expectedExpression.ToString(), actualExpression.ToString());
}
Поскольку у вас есть несколько тестовых примеров, которые не должны пройти, вероятно, у вас другая проблема.
ОБНОВЛЕНИЕ : Для вашего обновления рассмотрите следующие настройки и выражения:
string normal_type = "NORMAL";
// PersonConstants is a static class with NORMAL_TYPE defined as follows:
// public const string NORMAL_TYPE = "NORMAL";
Expression<Func<Person, bool>> expr1 = p => p.Type == normal_type;
Expression<Func<Person, bool>> expr2 = p => p.Type == PersonConstants.NORMAL_TYPE;
Одно выражение ссылается на переменную экземпляра содержащего метода. Другое представляет выражение, которое ссылается на член const статического класса. Это два разных выражения, независимо от значений, которые могут быть назначены переменным во время выполнения. Однако если string normal_type
изменяется на const string normal_type
, то выражения снова совпадают с каждой ссылкой a const
в правой части выражения.