在阅读了一些SO Q& A之后,我采用了不写自己的调度程序的推荐方法。我选择使用Quartz.net,因为它看起来完全符合我的需要。根据他们的快速入门指南,一旦调度程序被实例化,应用程序不应该关闭,直到我在调度程序上调用shutdown方法: http://www.quartz-scheduler.net/documentation/quartz-2.x/quick-start.html
我正在单元测试中对此进行测试,并且我发现我的nUnit测试正在关闭,而我没有在调度程序上调用shutdown!我让我的调度程序成为一个单例,假设它会解决它,但没有这样的运气。这种行为是否特定于单元测试?我假设因为它在我的测试中发生,所以当我稍后在我的控制台应用程序中使用它时会发生。
以下是我将调度程序放在一起的方法:
public static class Scheduler
{
public static IScheduler LocalScheduler { get; private set; }
static Scheduler()
{
// get a scheduler
ISchedulerFactory schedFact = new StdSchedulerFactory();
LocalScheduler = schedFact.GetScheduler();
}
public static void ScheduleJob(IJobDetail job, ITrigger trigger)
{
LocalScheduler.ScheduleJob(job, trigger);
}
public static void Start()
{
if (!LocalScheduler.IsStarted) LocalScheduler.Start();
}
public static void Stop()
{
LocalScheduler.Shutdown();
}
}
特别是失败的单元测试是:
[Test, Explicit]
public void JobExecutionTest()
{
var start = new DateTime(2014,06,01);
var stop = new DateTime(2014,06,10);
// I made my own factories for the JobDataMap, IJobDetail, and ITrigger.
var jobMap = JobDataFactory.CreateConnectwiseMap(start, stop);
var job = JobFactory.CreateParameterJob<ConnectwiseJob>("testjob", "testgroup", jobMap);
// fire in 5 seconds for testing
var trigger = TriggerFactory.CreateRecurring("testtrigger", "testgroup", DateTime.Now.AddSeconds(5));
Scheduler.ScheduleJob(job, trigger);
Scheduler.Start();
// it shuts down almost immediately!
}
我在应该执行的作业中放置了一个断点,以查看它是否被击中,它永远不会,因为单元测试认为它全部完成并关闭所有内容。我不想使用Thread.Sleep()如果我可以避免它,就像我在其他地方使用这个调度程序时我不希望它在那个状态下坐在那里。接听者是否会阻止它死亡?
答案 0 :(得分:3)
您的计划程序正在关闭,因为测试正在完成并且垃圾收集所有内容。如果你真的想让调度程序有时间完成它的事情,你必须通过在Scheduler.Start()之后添加一个Thread.Sleep语句来找到一种保持测试运行的方法。方法。
但是,你真的不想以这种方式测试你的工作。你应该模拟出IJobExecutionContext并将它传递给你的作业来执行。
答案 1 :(得分:0)
在使用早期版本的quartz之后,我记得调度程序在一个线程(或更多)中触发作业。多数民众赞成你可能会遇到的。所以也许你应该用另一种方法进行测试。
关心弗兰克