在xunit测试中模拟HostingEnvironment.QueueBackgroundWorkItem

时间:2015-02-11 14:18:03

标签: moq xunit .net-4.5.2

我有一个方法使用 HostingEnvironment.QueueBackgroundWorkItem我希望在此调用之前对某些行为进行单元测试,但是,测试失败了System.InvalidOperationException : Operation is not valid due to the current state of the object.

我怀疑这需要模拟HostingEnvironment但不知道如何。

3 个答案:

答案 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());
    }
}