设置模拟 class 方法以使用 Moq 执行 Func<Task> 参数

Setup a mocked class method to execute a Func<Task> parameter using Moq

我正在编写单元测试,其中涉及一个接受 Func<Task> 参数并在某些条件下执行的服务方法。

该方法如下所示:

public class ServiceA : IServiceA
{
   public async Task TryExecute(Func<Task> func, string foo)
   {
      // ... do unimportant things relating to string foo

      await func();
   }
}

调用 TryExecute 方法的服务如下所示

public class ServiceB : IServiceB
{
   private readonly IServiceA _serviceA;

   public ServiceB(IServiceA serviceA)
   {
      _serviceA = serviceA;
   }

   public async MethodThatCallsTryExecute(Bar bar)
   {
      // ... do unimportant things relating to bar

      await _serviceA.TryExecute(privateFunction, "baz");
   }
}

一个失败的单元测试示例,包括在调用 TryExecute 时尝试设置模拟结果,如下所示:

[Fact]
public async void TestName()
{
   // Arrange
   var serviceA = new Mock<IServiceA>();

   serviceA.Setup(a => a.TryExecute(It.IsAny<Func<Task>>(), It.IsAny<string>()))
      .Returns(async (Func<Task> func, string foo) => { await func(); });

   var serviceB = new ServiceB(serviceA.Object);

   var bar = new Bar();

   // Act
   await serviceB.MethodThatCallsTryExecute(bar);

   // Assert
   ... failing assertions

}

问题:在测试执行过程中,传入TryExecuteprivateFunction没有被执行(即调试时无法介入传入的 privateFunction 方法)。

如果还有什么我可以详细说明的,请告诉我;这是我在 Whosebug 上的第一个问题。

尝试将 MethodThatCallsTryExecute(Bar bar) 的签名更改为 return a Task 而不是 void (如果是的话),其余代码应该按预期工作,刚刚检查 privateFunction 被调用

public interface IServiceB
{
    Task MethodThatCallsTryExecute(Bar bar);
}

public class ServiceB : IServiceB
{
    private readonly IServiceA _serviceA;

    public ServiceB(IServiceA serviceA)
    {
        _serviceA = serviceA;
    }

    public async Task MethodThatCallsTryExecute(Bar bar)
    {
        // ... do unimportant things relating to bar

        Func<Task> privateFunction = () => Task.CompletedTask;
        await _serviceA.TryExecute(privateFunction , "baz");
    }
}

测试方法(或调用MethodThatCallsTryExecute的任何其他方法)的签名应更新为return a Task,例如

[Fact]
public async Task TestName()
{
}