使用 Moq 设置一个模拟的类方法来执行一个 Func<Task> 参数。

4

我正在编写单元测试,其中包含一个使用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方法)。

如果还有需要补充的信息,请告诉我;这是我在StackOverflow上的第一个问题。

1个回答

0
尝试更改MethodThatCallsTryExecute(Bar bar)的签名,使其返回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的其他方法)应更新为返回Task,例如:

[Fact]
public async Task TestName()
{
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接