EventHub PartitionContext类设计

问题描述 投票:1回答:1

我试图测试我的IEventProcessor的实现。但是,我很难,因为实际上不可能模拟PartitionContext类(https://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.partitioncontext.aspx)。

例如,我无法验证是否已正确调用CheckpointAsync()方法,因为ICheckpointer接口是内部的,实际方法不是虚拟的。此外,我不能注入我自己的ICheckpointManager实例,因为允许它的构造函数是内部的。

将所有内容制作成内部的设计决策是什么,这将允许我模拟这个类?

要么这是非常糟糕的设计,要么我错过了一些东西。

c# unit-testing azure-eventhub
1个回答
2
投票

是的,测试这个是很多工作。这是做什么的。

所以你创建了一个包装器:

public interface ICheckPointer
{
    Task CheckpointAsync(PartitionContext context);
}

public class CheckPointer : ICheckPointer
{
    public Task CheckPointAsync(PartitionContext context)
    {
        return context.CheckpointAsync();
    }
}

在单元测试方法中,您现在可以模拟接口并检查是否调用了CheckPointAsync

你现在的IEventProcessor实现应该接受ICheckPointer的一个实例:

public class SampleEventProcessor : IEventProcessor
{
    private ICheckPointer checkPointer;

    public SampleEventProcessor(ICheckPointer checkPointer)
    {
        this.checkPointer = checkPointer;
    }

    public Task OpenAsync(PartitionContext context)
    {
        return Task.FromResult<object>(null);
    }

    public async Task ProcessEventsAsync(PartitionContext context, IEnumerable<EventData> events)
    {
        ...

        await checkPointer.CheckpointAsync(context);
    }

    public async Task CloseAsync(PartitionContext context, CloseReason reason)
    {
        return Task.FromResult<object>(null);
    }
}

您将需要IEventProcessorFactory的实现来注入ICheckPoint接口:

internal class SampleEventProcessorFactory : IEventProcessorFactory
{
    private readonly ICheckPointer checkPointer;

    public SampleEventProcessorFactory (ICheckPointer checkPointer)
    {
        this.checkPointer = checkPointer;
    }

    public IEventProcessor CreateEventProcessor(PartitionContext context)
    {
        return new SampleEventProcessor(checkPointer);
    }
}

并像这样创建EventProcessor:

await host.RegisterEventProcessorFactoryAsync(new SampleEventProcessor(new CheckPointer()));

在单元测试中你现在可以做类似的事情(基于NSubstitute):

var mock = Substitute.For<ICheckPointer>();
var sample = new SampleEventProcessor(mock);
await sample.ProcessEventsAsync(new PartitionContext(), null);
mock.Received().CheckPointAsync(Arg.Any<PartitionContext>());

警告:没有编译代码,因此可能存在一些语法错误。至少它应该给你一个如何进行的基本想法。

© www.soinside.com 2019 - 2024. All rights reserved.