2017-01-25 1 views
6

J'ai une application Web qui effectue un traitement en arrière-plan via QueueBackgroundWorkItem.QueueBackgroundWorkItem de Microsoft.VisualStudio.TestTools.UnitTesting

Je suis câblage des tests unitaires pour la fonctionnalité dans l'application et quand il tente d'invoquer ce que je reçois l'erreur suivante:

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) 

La comparaison des environnements entre le moment où cela s'invoqué à partir d'un test unitaire vs quand il est invoqué dans le cadre d'un serveur Web en cours d'exécution, je vois que le AppDomain/HostingEnvironment sont différents. Sans faire un déploiement d'application Web complet pour les tests, existe-t-il un moyen de structurer le test unitaire afin que l'élément de travail en arrière-plan puisse s'exécuter dans le contexte approprié? Simplement sans modifier le code cible existant, en changeant simplement le code de test - et si cela n'est pas possible, utilisez éventuellement IOC pour exécuter l'élément de travail en arrière-plan dans un thread d'arrière-plan approprié en fonction de son contexte.

mise à jour

Cela fonctionne, bien que probablement il y a une façon plus élégante de le faire. Fondamentalement, ne l'exécute fond si elle est invoquée à partir d'un environnement hébergé:

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

Répondre

1

Je sais qu'il est un peu moche, mais je fini par créer ma propre classe d'aide

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

Et changé toutes les références à QueueBackgroundWorkItem à cette classe