2010-08-24 3 views
3

Silverlight Toolkit contient une fonctionnalité de test unitaire qui permet de tester des classes telles que ViewModels dans une application MVVM qui appelle des services distants de manière asynchrone.Intégration Test d'un ViewModel qui appelle les services WCF de manière asynchrone dans une application WPF MVVM

J'aimerais pouvoir effectuer mes tests d'intégration de ViewModel par rapport aux services réels au lieu des instances simulées.

Existe-t-il une prise en charge des tests d'unité/d'intégration asynchrones pour les applications WPF?

Mise à jour:

A la fin de la journée ma solution combine les suggestions de ktutnik et Alex Paven. J'ai écrit une petite classe d'aide qui ajoute un peu de sucre syntaxique:

public static class AsyncMethod 
{ 
    public delegate void AsyncMethodCallback(AsyncMethodContext ctx); 

    public static void Call(AsyncMethodCallback cb) 
    { 
     // create the sync object and make it available via TLS 
     using (var syncObject = new AutoResetEvent(false)) 
     { 
      // call the decorated method 
      cb(new AsyncMethodContext(syncObject)); 
     } 
    } 
} 

/// <summary>Asnc Method Callback Synchronization Context</summary> 
public class AsyncMethodContext 
{ 
    public AsyncMethodContext(EventWaitHandle syncObject) 
    { 
     this.syncObject = syncObject; 
    } 

    private readonly EventWaitHandle syncObject; 

    /// <summary> 
    /// Waits for completion. 
    /// </summary> 
    public void WaitForCompletion() 
    { 
     syncObject.WaitOne(); 
    } 

    /// <summary> 
    /// Signals the current operation as complete 
    /// </summary> 
    public void Complete() 
    { 
     syncObject.Set(); 
    } 
} 

est ici un cas de test d'échantillon combiné avec l'utilisation de Microsoft Rx Extensions:

[TestMethod] 
public void TestGuestLogin() 
{ 
    AsyncMethod.Call((ctx) => 
    { 
     var vm = ServiceLocator.Get<LoginDialogViewModel>(); 

     // setup VM data 
     vm.Username = "guest"; 
     vm.Password = "guest"; 
     vm.AutoLogin = false; 
     GenericInfoEventArgs<LoginDialogViewModel.LoginRequestResult> loginResult = null; 

     // pre-flight check 
     Assert.IsTrue(vm.LoginCmd.CanExecute(null)); 

     // create Observable for the VM's LoginRequestComplete event 
     var loginEvent = Observable.FromEvent<GenericInfoEventArgs<LoginDialogViewModel.LoginRequestResult>>(vm, "LoginRequestComplete").Do((e) => 
     { 
      Debug.WriteLine(e.ToString()); 
     }); 

     // subscribe to it 
     var loginEventSubscription = loginEvent.Subscribe((e) => 
     { 
      loginResult = e.EventArgs; 

      // test complete 
      ctx.Complete(); 
     }); 

     // set things in motion 
     using (loginEventSubscription) 
     { 
      vm.LoginCmd.Execute(null); 
      ctx.WaitForCompletion(); 

      Assert.IsTrue(loginResult.Info.Success, "Login was not successful"); 
     } 
    }); 
} 

Répondre

3

Je cherchais depuis longtemps pour cette caractéristique, mais encore malchanceux.

Pas vraiment une solution propre mais c'est un travail pour moi. J'ai l'habitude d'utiliser ManualResetEvent afin que le processus de test ne tombe pas jusqu'à asynchrone fait. Voici l'idée:

//set false for initial state 
resetEvent = new ManualResetEvent(false); 
//do the test 
myObjec.MakeMeHappyAssync(); 
//just wait until its state set 
//when your call done 
resetEvent.WaitOne(); 
//do assertion here 

Et quelque part sur votre méthode complète ou d'une méthode de défaut que vous appelez simplement

resetEvent.Set(); 

Quoi qu'il en soit si vous avez trouvé de nouvelles informations sur la fonction s'il vous plaît laissez-moi savoir

Best Regard

+0

Malheureusement, c'est ce que ma solution s'est finalement résumée. Voir ma mise à jour post. –

1

Vous pouvez vous intéresser aux extensions réactives, qui sont maintenant incluses dans .Net Framework 4, en supposant que vous l'utilisiez; il y a aussi des versions pour 3.5 et Silverlight. Ils permettent un bon codage asynchrone, je les ai déjà utilisés dans des tests unitaires. Voir here pour un article de blog en discuter.

+0

Excellente suggestion. Lire et utiliser cette bibliothèque est une véritable révélation. –

Questions connexes