【问题标题】:How to mock delegates correctly如何正确模拟代表
【发布时间】:2020-06-10 11:17:10
【问题描述】:

我有一个这样的接口和实现:

public interface IScopedServices
{
   Task<TReturn> ExecuteAsync<TService, TReturn>(Func<TService, Task<TReturn>> action);
}

//Implemented like so:

public async Task<TReturn> ExecuteAsync<TService, TReturn>(Func<TService, Task<TReturn>> action)
{
   using (var serviceScope = serviceScopeFactory.CreateScope())
   {
      var service = serviceScope.ServiceProvider.GetService<TService>();
      return await action.Invoke(service);
   }
}

此服务包装了其他服务调用,因此它们可以获得自己的范围,这样的服务调用的示例是:

public class TicketService : ITicketService
{
   public async Task<Ticket> GetTicket(string ticketNumber)
   {
      return await repository.Get(t => t.TicketNumber == ticketNumber);
   }
}

这在我的测试代码中被调用,如下所示:

var ticket = await ScopedServices.ExecuteAsync<ITicketService, Ticket>(s => s.GetTicket("ticket number"));

所以在我的单元测试中,我这样模拟它,它工作正常,没问题:

var mockScopedServices = new Mock<IScopedServices>();

mockScopedServices.Setup(mss => mss.ExecuteAsync(It.IsAny<Func<ITicketService, Task<Ticket>>>())).ReturnsAsync(TestTicket);

我的问题是:我如何模拟 ITicketService 以便在使用特定参数调用 GetTicket 时返回一个单独的对象?

现在,由于我是 Moq 的新手,我不确定如何模拟 ITicketService,以便我可以控制 GetTicket 将什么作为参数以及在这种情况下返回什么。

【问题讨论】:

  • 使用Callback捕获传入的委托,然后调用它。

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


【解决方案1】:

您可以使用Callback 捕获传入的委托,然后调用它。

这在一定程度上是在模拟实现的内部运作。

但实际上可以在 Returns 委托中完成同样的操作

var scopedMock = new Mock<ITicketService>();
scopedMock 
    .Setup(_ => _.GetTicket(It.IsAny<string>())) // <-- setup and adjust as needed
    .ReturnsAsync(TestTicket);

var mockScopedServices = new Mock<IScopedServices>();
mockScopedServices
    .Setup(_ => _.ExecuteAsync(It.IsAny<Func<ITicketService, Task<Ticket>>>()))
    .Returns((Func<ITicketService, Task<Ticket>> arg) => {
        //this invokes the passed in delegate using the mocked scoped service
        Task<Ticket> task = arg(scopedMock.Object);
        return task;
    });

【讨论】:

    猜你喜欢
    • 2021-08-30
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-02
    • 2019-06-10
    • 2018-09-25
    相关资源
    最近更新 更多