繁体   English   中英

如何在 xUnit 中模拟委托

[英]How to mock Delegate in xUnit

我有委托调用SendMessagesAsync方法,该方法采用 IEnumerable ProviderExemptionReceivedNotification。 我如何模拟作为委托回调的 SendMessagesAsync。 换句话说,我如何起订量委托?

Interface

public delegate Task<bool> SendAnprProviderExemptionNotifications(IEnumerable<ProviderExemptionReceivedNotification> exemptions);

public interface IRingGoApiService
{
    Task<RingGoMessageResponseResult> ProcessCreateRequestAsync(RingGoExemption ringGoExemption, SendAnprProviderExemptionNotifications sendProviderExemption);
}

Delegate Implementation

public async Task<RingGoMessageResponseResult> ProcessCreateRequestAsync(RingGoExemption ringGoExemption, SendAnprProviderExemptionNotifications sendProviderExemption)
    {
       var msgSent = await sendProviderExemption(new List<ProviderExemptionReceivedNotification>() { exemption });
    }

Test Class

public MyTestClass{
 
public MyTestClass()
{
}

private readonly Mock<IProviderExemptionService> providerExemptionServiceMoq;
}

using delegate

var result = await _ringGoApiService.ProcessCreateRequestAsync(ringGoExemption,
async (IEnumerable<ProviderExemptionReceivedNotification> exemptions) => await SendMessagesAsync(servicebusMessage, exemptions)
                    );

SendMessagesAsync

static async Task<bool> SendMessagesAsync(IAsyncCollector<Message> collector, IEnumerable<ProviderExemptionReceivedNotification> exemptions)
    {
        SetProviderExemption(exemptions);

        var messages = exemptions.Select(exemption =>
        {
            //Creating ServiceBus Message...

            return message;
        });
    }

    static void SetProviderExemption(IEnumerable<ProviderExemptionReceivedNotification> exemptions)
    {
        providerExemption = exemptions.FirstOrDefault();
    }

你不能嘲笑一个代表。 您也不能模拟该表达式,因为它被硬编码到被测对象中。

您需要在 Moq Callback中捕获委托并在那里调用它。 鉴于显示的测试对象,这是唯一可用的选项。

这是基于您之前的帖子的被测主题的过度简化的最小可重现示例。

public delegate Task<bool> SendAnprProviderExemptionNotifications(IEnumerable<ProviderExemptionReceivedNotification> exemptions);

public interface IRingGoApiService {
    Task<RingGoMessageResponseResult> ProcessCreateRequestAsync(RingGoExemption ringGoExemption, SendAnprProviderExemptionNotifications sendProviderExemption);
}

public class RingGoMessageResponseResult { }

public class ProviderExemptionReceivedNotification { }

public class RingGoExemption : Exception { }

public interface IActionResult { }

public class OverSimplifiedExample {
    private readonly IRingGoApiService ringGoApiService;

    public OverSimplifiedExample(IRingGoApiService ringGoApiService) {
        this.ringGoApiService = ringGoApiService;
    }

    public async Task<bool> Run() {

        RingGoExemption ringGoExemption = new RingGoExemption();

        RingGoMessageResponseResult result = await ringGoApiService.ProcessCreateRequestAsync(ringGoExemption, myDelegate);

        return result != null;
    }

    private Task<bool> myDelegate(IEnumerable<ProviderExemptionReceivedNotification> exemptions) {
        return Task.FromResult(true);
    }
}

上面提供的主题测试,包括捕获委托(处理程序)并调用它的Callback ,实际上在执行时按预期运行。

[TestFixture]
public class MyTestClass {
    [Test]
    public async Task MyTestMethod() {
        //Arrange
        Mock<IRingGoApiService> mock = new Mock<IRingGoApiService>();
        RingGoMessageResponseResult ringGoMessageResponseResult = new RingGoMessageResponseResult();

        mock
            .Setup(_ => _.ProcessCreateRequestAsync(It.IsAny<RingGoExemption>(), It.IsAny<SendAnprProviderExemptionNotifications>()))
            .ReturnsAsync(ringGoMessageResponseResult)
            .Callback((RingGoExemption exception, SendAnprProviderExemptionNotifications handler) => {
                var whateverMyExemptionsAre = Enumerable.Empty<ProviderExemptionReceivedNotification>();
                handler.Invoke(whateverMyExemptionsAre);
            });

        var subject = new OverSimplifiedExample(mock.Object);

        //Act
        var actual = await subject.Run();

        //Assert
        actual.Should().BeTrue();
    }
}

您将需要调整此示例以适应您正在尝试做的事情。 它不会完全按照这里写的那样复制。

您可能仍然会遇到问题,因为您没有展示SendMessagesAsync正在做什么以确保可以通过其调用来模拟安全路径。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM