无法使用 Moq 框架验证 Select() 内部调用的方法

Can't verify method called inside Select() using Moq framework

我在验证是否在 LINQ Select() 查询中模拟调用了某些方法时遇到问题。

下面是我要测试的ContentManager方法:

public string ProcessElements(List<Item> items)
{
    var processed = items.Select(item => item.Process(Constants.Text));

    return Serialize(processed);
}

我想测试是否为列表的元素调用了 Process()。我的测试方法如下所示:

[TestMethod]
public void ProcessItems_ValidItems_ProcessCalled()
{
    var contentManager = new ContentManager();
    var itemMock = new Mock<Item>();
    itemMock.Setup(m => m.Process(It.IsAny<string>()))
        .Returns("serialized");

    contentManager.ProcessElements(new List<Item>() { itemMock.Object });

    itemMock.Verify(m => m.Process(It.IsAny<string>()), Times.Once());
}

当我 运行 这个测试失败时 returns 出现以下消息:

Test method ProcessItems_ValidItems_ProcessCalled threw exception:

Moq.MockException:

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

m => m.Process(It.IsAny())

No setups configured.

No invocations performed.

但是 如果我将 Select() 更改为 foreach,则测试成功通过:

public string ProcessElements(List<Item> iitem)
{
    var processed = new List<string>();
    foreach (var item in iitem)
    {
        processed.Add(item.Process(Constants.Text));
    }

    return Serialize(processed);
}

Moq + Select() 有什么问题?我该如何解决这个问题?

不确定 .Serialize 方法做什么,但 .Select 没有 运行 实际查询它只是 returns 一个知道如何遍历 [=12] 的对象=].

使用 .Where.Select 等多个 LINQ 方法,您可以构建稍后通常通过 foreach 或调用 .ToList.ToDictionary

因此,对于 运行,LINQ 查询将其更改为:

.Select(...)

收件人:

.Select(...).ToList()