来自Microsoft.VisualStudio.TestTools.UnitTesting的QueueBackgroundWorkItem

时间:2017-01-25 22:06:31

标签: c# asp.net vs-unit-testing-framework

我有一个Web应用程序,它通过QueueBackgroundWorkItem在后台进行一些处理。

我为应用程序中的功能连接单元测试,当它试图调用它时,我收到以下错误:

System.InvalidOperationException occurred
  HResult=-2146233079
  Message=Operation is not valid due to the current state of the object.
  Source=System.Web
  StackTrace:
       at System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem(Func`2 workItem)

比较从单元测试调用它到作为正在运行的Web服务器的一部分调用它之间的环境,我发现AppDomain / HostingEnvironment是不同的。

如果没有完整的Web应用程序部署进行测试,是否有办法构建单元测试,以便后台工作项可以在适当的上下文中运行?

最好不要更改现有目标代码,只需更改测试代码 - 如果不可能,可以使用IOC根据其上下文在适当的后台线程中运行后台工作项。

更新

虽然可能有一种更优雅的方式,但仍有效。基本上只有在从托管环境调用时才运行它后台:

private void GetSomeData(SomeCriteria criteria, Dictionary<int, List<Tuple<int, string>>> someParam)
{
    if (System.Web.Hosting.HostingEnvironment.IsHosted)
    {
        System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem((token) =>
        {
            GenerateSomeData(token, criteria, someParam);
        });
    }
    else
    {
        CancellationToken token = new CancellationToken();
        GenerateSomeData(token, criteria, someParam);
    }
}

1 个答案:

答案 0 :(得分:2)

我知道它有点丑,但我最终创建了自己的助手类

public static class BackgroundWorkItemX
{
    public static void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
    {
        try
        {
            HostingEnvironment.QueueBackgroundWorkItem(workItem);
        }
        catch (InvalidOperationException)
        {
            workItem.Invoke(new CancellationToken());
        }
    }
}

并将对QueueBackgroundWorkItem的所有引用更改为此类