2015-02-11 11 views
14

ich eine Methode, mit HostingEnvironment.QueueBackgroundWorkItem, die ich Unit-Test vor diesem Aufruf einige Verhalten wünschen, jedoch wird der Test mit System.InvalidOperationException : Operation is not valid due to the current state of the object.Mock HostingEnvironment.QueueBackgroundWorkItem in xunit Test

versagt Ich vermute, das ich brauche die Hostingenvironment verspotten aber nicht bewusst wie.

Antwort

28

Um dieses Problem zu beheben ich eine Schnittstelle I injizieren Implementierung

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

Im Testcode

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

In Produktionscode definiert spritze ich Implementierung

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

Ich denke, das eine ist OK Lösung, da Komponententests funktionieren und meine Klassen, die Hintergrundaufgaben auflisten, entkoppelt sind von HostingEnvironment.

+3

Dies ist, wie es sollte entkoppeln d! Sollte die akzeptierte Antwort sein! – Mrchief

5

endete ich Dinge zu tun, dies zu halten einfach:

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

Dann einfach einen Job zu feuern:

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

Ein wenig sauberer als HostingEnvironment.QueueBackgroundWorkItem Aufruf unabhängig davon, ob es eine ASP.NET AppDomain fängt dann die InvalidOperationException ist:

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