具有多个布尔条件的Moq验证参数

时间:2015-11-04 09:51:48

标签: c# unit-testing tdd moq

我试图让我的测试尽可能可读和可维护,并且我希望将这种形式的参数对象验证传递给我提供给SUT的模拟。< / p>

_emailHelperMock.Verify(eh => eh.OnMailCreated(
            It.Is<MailMessage>(WithBodyContaining(enrolment) && SentTo(Test.CustomerAddress))));

但是,由于我收到编译错误,我还没有找到解决方法:

Error   CS0019  Operator '&&' cannot be applied to operands of type 'Expression<Func<MailMessage, bool>>' and 'Expression<Func<MailMessage, bool>>'

以上使用的句法糖方法按以下方式定义:

    private static Expression<Func<MailMessage, bool>> WithBodyContaining(Enrolment enrolment)
    {
        return mail => mail.Body.Contains(enrolment.Title) && mail.Body.Contains(enrolment.Date);
    }

    private static Expression<Func<MailMessage, bool>> SentTo(string address)
    {
        return mail => mail.To.ToString().Contains(address);
    }

我可以制作一个方法,例如WithBodyContainingEnrolmentAndSentToAddress(enrolment, address),但我更喜欢上面已经说过多次布尔检查的表单。

2 个答案:

答案 0 :(得分:0)

如果您更改方法以返回bool而不是Expression<Func<MailMessage, bool>> s,那么您可以将它们组合在一起,我认为无论如何它们都会更清晰。例如:

_emailHelperMock.Verify(eh => eh.OnMailCreated(It.Is<MailMessage>(mail => WithBodyContaining(mail, enrolment) && SentTo(mail, Test.CustomerAddress)

private static bool WithBodyContaining(MailMessage mail, Enrolment enrolment)
{
    return mail.Body.Contains(enrolment.Title) && mail.Body.Contains(enrolment.Date);
}

private static bool SentTo(MailMessage mail, string address)
{
    return mail.To.ToString().Contains(address);
}

答案 1 :(得分:0)

你必须组合表达式:

public static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
        {
            var param = expr1.Parameters[0];
            if (ReferenceEquals(param, expr2.Parameters[0]))
            {
                return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, expr2.Body), param);
            }
            return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, Expression.Invoke(expr2, param)), param);
        }