如何测试使用 Schedule 的 NServiceBus 处理程序
How to test an NServiceBus handler that uses Schedule
我正在玩一个实现 IWantToRunWhenBusStartsAndStops
的简单处理程序,一开始,它会安排一个任务,如下所示:
public void Start()
{
_schedule.Every(TimeSpan.FromSeconds(5), Moo);
}
_schedule 通过构造函数注入。我正在尝试编写的测试是确保在处理程序启动时安排任务。但是我找不到模拟 Schedule 的方法,因为它没有无参数构造函数,也没有实现接口。我尝试用模拟的 IBuilder
创建它的实际实例,但无法弄清楚要在 IBuilder
上设置什么期望。另外,我查看了源代码以了解他们是如何测试 Schedule
但看起来我们使用的是早期版本(v5.0.0 通过 nuget),因为我们没有出现 DefaultScheduler
成为他们在当前测试中使用的内容。
事实上,NServiceBus 团队已经用 unit/acceptance 测试覆盖了调度程序,即当您的处理程序执行时,无需检查任务是否实际调度。相反,您可能希望对处理程序本身进行单元测试,从而检查是否已调用 scheduler.Every() 。这是您的单元测试的简单示例:
[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;
}
}
我正在玩一个实现 IWantToRunWhenBusStartsAndStops
的简单处理程序,一开始,它会安排一个任务,如下所示:
public void Start()
{
_schedule.Every(TimeSpan.FromSeconds(5), Moo);
}
_schedule 通过构造函数注入。我正在尝试编写的测试是确保在处理程序启动时安排任务。但是我找不到模拟 Schedule 的方法,因为它没有无参数构造函数,也没有实现接口。我尝试用模拟的 IBuilder
创建它的实际实例,但无法弄清楚要在 IBuilder
上设置什么期望。另外,我查看了源代码以了解他们是如何测试 Schedule
但看起来我们使用的是早期版本(v5.0.0 通过 nuget),因为我们没有出现 DefaultScheduler
成为他们在当前测试中使用的内容。
事实上,NServiceBus 团队已经用 unit/acceptance 测试覆盖了调度程序,即当您的处理程序执行时,无需检查任务是否实际调度。相反,您可能希望对处理程序本身进行单元测试,从而检查是否已调用 scheduler.Every() 。这是您的单元测试的简单示例:
[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;
}
}