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");
}
});
}
Malheureusement, c'est ce que ma solution s'est finalement résumée. Voir ma mise à jour post. –