如何测试使用计划的 NServiceBus 处理程序



我正在使用一个简单的处理程序来实现IWantToRunWhenBusStartsAndStops,并且在开始时,它会像这样安排任务:

    public void Start()
    {
        _schedule.Every(TimeSpan.FromSeconds(5), Moo);
    }

_schedule是通过构造函数注入的。我尝试编写的测试是确保在处理程序启动时计划任务。但是我找不到一种方法来模拟 Schedule,因为它没有 no-arg 构造函数,也没有实现接口。我尝试使用模拟IBuilder创建它的实际实例,但无法弄清楚对IBuilder设置什么期望。另外,我查看了源代码以了解他们如何测试Schedule但看起来我们使用的是早期版本(通过 nuget 的 v5.0.0),因为我们没有DefaultScheduler似乎是他们在当前测试中使用的。

事实上,NServiceBus 团队已经用单元/验收测试覆盖了调度程序,即在执行处理程序时,无需检查任务是否实际调度。相反,您可能希望对处理程序本身进行单元测试,从而检查是否调用调度程序。每个()都已制作完成。下面是单元测试的简单示例:

[TestClass]
public class Tests
{
    [TestMethod]
    public void When_executing_handler_the_task_should_be_scheduled()
    {
        //arrange
        var scheduler = new FakeSheduler();
        //act
        var handler = new TestHandler(scheduler);
        handler.Start();
        //assert
        Assert.IsTrue(scheduler.WasCalled);
    }
}

处理程序本身:

class TestHandler: IWantToRunWhenBusStartsAndStops
{
    readonly IMyScheduler _scheduler;
    public TestHandler(IMyScheduler scheduler)
    {
        _scheduler = scheduler;
    }
    public void Start()
    {
        _scheduler.Every(TimeSpan.FromSeconds(5), () => { });
    }
    public void Stop() { }
}

最后,您必须从直接使用 NServiceBus 调度程序中抽象出来,以使其可测试,这是这个想法:

interface IMyScheduler
{
    void Every(TimeSpan interval, Action action);
}
//your real implementation
class MySheduler: IMyScheduler
{
    readonly Schedule _schedule;
    public MySheduler(Schedule schedule)
    {
        _schedule = schedule;
    }
    public void Every(TimeSpan interval, Action action)
    {
        _schedule.Every(TimeSpan.FromSeconds(5), () => { });
    }
}
//fake for the testing
class FakeSheduler: IMyScheduler
{
    public bool WasCalled { get; set; }
    public void Every(TimeSpan interval, Action action)
    {
        WasCalled = true;
    }
}

最新更新