【问题标题】:Moq method that uses lambda and verify its return使用 lambda 并验证其返回的 Moq 方法
【发布时间】:2020-03-05 23:21:41
【问题描述】:

建议的答案使用 It.IsAny,我们坚决不使用它。

所以我正在尝试验证 Expression<Func<Foo, bool>> 并在我的收藏中运行它:

Expression<Func<Foo, bool>> testExpression = exp =>
    exp.Bars.Any(a => a.Bar.BarString == barString);

_fooRepository.Setup(f => f.GetAllListAsync(It.Is<Expression<Func<Foo, bool>>> 
   (exp => exp == testExpression)))
.Returns(Task.FromResult(fooList.Where(testExpression.Compile()).ToList()))
.Verifiable();

我对答案进行了多次尝试,但是用谓词重载 return 并不能让我在强类型列表上执行它。


我有一个方法,它接受一个字符串并在存储库上执行一个 lambda 以获取所有匹配的实例(但只需要一个)。

例如:

    var foo = await _fooRepository.GetAllListAsync(
        f => f.Bars.Any(b => b.Bar.BarString == barString));

有一些验证可以确保只返回一个 - 然后返回 foo 的属性(我们会说 fooId)。

我遇到的问题是设置一个可以验证的模拟 - 给定 Foo 的列表,lambda 是否返回预期结果?

我的测试在这一点上相当糟糕(我一直在重写它并且研究它太久了):

const string fooId = "fooId";
const string barString = "barString";
var fooList = new List<FooList>()
{
    new Foo()
    {
        FooId = fooId,
        Bars = new List<FooBar>()
        {
            new FooBar()
            {
                Bar = new Bar()
                {
                    BarString = barString
                }
            }
        }
    },
    new Foo()
    {
        FooId = "other foo",
        Bars = new List<FooBar>()
        {
            new FooBar()
            {
                Bar = new Bar()
                {
                    BarString = "other bars"
                }
            }
        }
    }

};

_fooRepository.Setup(f => f.GetAllListAsync(It.IsAny<Expression<Func<Foo, bool>>>()))
    .Returns(Task.FromResult(fooList))
    .Verifiable();

我尝试通过以下方式构建一个 expectedExpression:

Expression<Func<Foo, bool>> expectedExpression = exp => 

这就是我挂的地方——因为,我可以毫不费力地创造出这种表达方式。我不知道如何让我的 fooList 让表达式在它上面执行。

我已经看到了 .Returns() 方法中使用 Lambda 的一些示例 - 但这似乎不是我希望它采用的路线,因为我希望它测试 方法,不是我提供测试的 lambda。

任何方向都将不胜感激。

【问题讨论】:

  • ^ 该示例确实使用了 Returns() 方法,但我相信这是您应该采用的方法。答案中Returns() 的重载提供了传递给方法的表达式的值。您可以针对您的 fooList 使用该表达式,以确保它正确过滤结果
  • 虽然我已经看过那个 - 我确实回去尝试过,但也许我错过了一些东西。

标签: c# lambda moq


【解决方案1】:

我缺少的是我必须传递整个迭代的预期结果。

例如:

var fooList = new List<FooList>()
{
    new Foo()
    {
        FooId = fooId,
        Bars = new List<FooBar>()
        {
            new FooBar()
            {
                Bar = new Bar()
                {
                    BarString = barString
                }
            }
        }
    },
    new Foo()
    {
        FooId = "other foo",
        Bars = new List<FooBar>()
        {
            new FooBar()
            {
                Bar = new Bar()
                {
                    BarString = "other bars"
                }
            }
        }
    }

};

然后我必须用预期的结果声明迭代:

Func<Expression<Func<Foo, bool>>, bool> exprIsGood = expr => 
{
    var func = expr.Compile();

    return func(fooList[0])
        && !func(fooList[1]);
};

最后,我可以验证 lambda 并传递预期回报:

_fooRepository.Setup(
    f => f.GetAllListAsync(
        It.Is<Expression<Func<Foo, bool>>>(exp => exprIsGood(exp))))
    .Returns(Task.FromResult(new List<Foo> { fooList[0] }))
    .Verifiable();

【讨论】:

    猜你喜欢
    • 2011-10-02
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多