Silverlight 工具包包含单元测试功能,允许测试异步调用远程服务的 MVVM 应用程序中的 ViewModel 等类。
我希望能够针对实际服务而不是模拟实例执行我的 ViewModel 集成测试。
是否支持 WPF 应用程序的异步单元/集成测试?
更新:
最终,我的解决方案结合了 ktutnik 和 Alex Paven 的建议。我写了一个添加了一些语法糖的小助手类:
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();
}
}
下面是结合使用 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");
}
});
}
最佳答案
我一直在寻找这个功能,但不幸的是。
这不是一个真正干净的解决方案,但它对我有用。我通常使用 ManualResetEvent
所以测试过程在异步完成之前不会失败。这是想法:
//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
在您的 Complete Method 或 Fault Method 中的某处,您只需调用
resetEvent.Set();
无论如何,如果您发现有关该功能的任何新信息,请告诉我
最好的问候
关于wpf - 集成测试在 WPF MVVM 应用程序中异步调用 WCF 服务的 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3559554/