【问题标题】:How to return passed parameters in an async method with Moq in unit tests?如何在单元测试中使用 Moq 在异步方法中返回传递的参数?
【发布时间】:2026-02-10 09:20:05
【问题描述】:

我正在努力解决如何使用 Moq-Setup-Return 构造的问题。

首先,我的设置:

IRepository-Interface 类型的某些存储库必须实现 StoreAsync-Method,该方法返回一个 StoreResult 对象,其中包含存储的实体作为属性。

using System.Threading.Tasks;
using Moq;
using Xunit;

namespace Tests
{
    public class Entity { }

    public class StoreResult
    {
        public Entity Entity { get; set; }
    }

    public interface IRepository
    {
        Task<StoreResult> StoreAsync(Entity entity);
    }

    public class Tests
    {
        [Fact]
        public void Test()
        {
            var moq = new Mock<IRepository>();
            moq.Setup(m => m.StoreAsync(It.IsAny<Entity>())).Returns(e => Task.FromResult<Task<StoreResult>>(new StoreResult {Entity = e}));
        }
    }
}

现在我尝试为 IRepository-Interface 编写一个 Mock-Objekt,但我不知道如何编写 Return-Statement,以便 StoreResult-Object 包含作为参数提供给 StoreAsync-Function 的实体。

我在Moq ReturnsAsync() with parametersReturning value that was passed into a method 中读到过这个话题。

我试过了

moq.Setup(m => m.StoreAsync(It.IsAny<Entity>()))
     .ReturnsAsync(entity => new StoreResult {Entity = entity});

带有错误语句“无法将 lambda 表达式转换为类型“StoreResult”,因为它不是委托类型。

我尝试过同样的错误消息

moq.Setup(m => m.StoreAsync(It.IsAny<Entity>()))
     .Returns(e => Task.FromResult<Task<StoreResult>>(new StoreResult {Entity = e}));

我正在使用带有 Moq 4.6.36-alpha 的 .NET Core xUnit 环境

感谢您的帮助。

【问题讨论】:

  • 不应该只是:Task.FromResult&lt;StoreResult&gt;(new StoreResult {Entity = e})
  • @CallumLinington - .Returns(Task.FromResult&lt;StoreResult&gt;(new StoreResult {Entity = e})); e 未定义。
  • It.IsAny 就是这样做的。给它一个合适的实体!!!
  • @CallumLinington 啊啊,我明白了。 moq.Setup(m =&gt; m.StoreAsync(It.IsAny&lt;Entity&gt;())).Returns((Entity e) =&gt; Task.FromResult(new StoreResult {Entity = e})); 成功了。
  • @NateBarbettini - 哦,是的,这解决了问题。对于记录,我添加了信息作为答案。

标签: c# unit-testing moq .net-core


【解决方案1】:

感谢 Callum Linigton 的提示,我找到了以下解决方案:

moq
 .Setup(m => m.StoreAsync(It.IsAny<Entity>()))
 .Returns((Entity e) => Task.FromResult(new StoreResult {Entity = e}));

关键区别在于为 lambda 表达式的输入参数指定类型,以避免模棱两可的调用。

【讨论】: