Mock HostingEnvironment.QueueBackgroundWorkItem in xunit test

眉间皱痕 提交于 2020-01-02 00:42:46

问题


I have a method using HostingEnvironment.QueueBackgroundWorkItem which I wish to unit test some behaviour before this call, however, the test is failing with System.InvalidOperationException : Operation is not valid due to the current state of the object.

I suspect this I need to mock the HostingEnvironment but unaware of how to.


回答1:


To resolve this issue I defined an interface

public interface ITaskScheduler
{
    void QueueBackgroundWorkItem(Action<CancellationToken> workItem);
}

In production code I inject implementation

public class AspNetTaskScheduler : ITaskScheduler
{
    public void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
    {            
        HostingEnvironment.QueueBackgroundWorkItem(workItem);
    }
}

In test code I inject implementation

public class TaskScheduler : ITaskScheduler
{
    public void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
    {
        workItem.Invoke(new CancellationToken());
    }
}

I think this is an OK solution since unit tests work and my classes that queue background tasks are decoupled from HostingEnvironment.




回答2:


I ended up doing this to keep things simple:

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

Then to fire a job simply:

BackgroundTaskScheduler.QueueBackgroundWorkItem(ct =>
{
     // bla
});



回答3:


A little bit neater than calling HostingEnvironment.QueueBackgroundWorkItem regardless of whether there's an ASP.NET AppDomain then catching the InvalidOperationException is:

public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
{
    if (HostingEnvironment.IsHosted)
    {
        HostingEnvironment.QueueBackgroundWorkItem(workItem);
    }
    else
    {
        workItem.Invoke(new CancellationToken());
    }
}


来源:https://stackoverflow.com/questions/28456590/mock-hostingenvironment-queuebackgroundworkitem-in-xunit-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!