我有一个方法使用
HostingEnvironment.QueueBackgroundWorkItem
我希望在此调用之前对某些行为进行单元测试,但是,测试失败了System.InvalidOperationException : Operation is not valid due to the current state of the object.
我怀疑这需要模拟HostingEnvironment但不知道如何。
答案 0 :(得分:31)
要解决此问题,我定义了一个接口
public interface ITaskScheduler
{
void QueueBackgroundWorkItem(Action<CancellationToken> workItem);
}
在生产代码中我注入实现
public class AspNetTaskScheduler : ITaskScheduler
{
public void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
{
HostingEnvironment.QueueBackgroundWorkItem(workItem);
}
}
在测试代码中我注入实现
public class TaskScheduler : ITaskScheduler
{
public void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
{
workItem.Invoke(new CancellationToken());
}
}
我认为这是一个很好的解决方案,因为单元测试工作,我排队后台任务的类与HostingEnvironment
分离。
答案 1 :(得分:5)
我最后这样做是为了简单起见:
/// <summary>
/// add some jobs to the background queue
/// </summary>
public static class BackgroundTaskScheduler
{
/// <summary>
/// send the work item to the background queue
/// </summary>
/// <param name="workItem">work item to enqueue</param>
public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
{
try
{
HostingEnvironment.QueueBackgroundWorkItem(workItem);
}
catch (InvalidOperationException)
{
workItem.Invoke(new CancellationToken());
}
}
}
然后简单地解雇一份工作:
BackgroundTaskScheduler.QueueBackgroundWorkItem(ct =>
{
// bla
});
答案 2 :(得分:1)
比调用HostingEnvironment.QueueBackgroundWorkItem
更整洁,无论是否有ASP.NET AppDomain,然后捕获InvalidOperationException
:
public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
{
if (HostingEnvironment.IsHosted)
{
HostingEnvironment.QueueBackgroundWorkItem(workItem);
}
else
{
workItem.Invoke(new CancellationToken());
}
}