Integration Testing a ViewModel that invokes WCF services asynchronously in an MVF MVPF application

The Silverlight Toolkit contains unit testing functionality that allows you to test classes, such as ViewModels in an MVVM application, that invoke remote services asynchronously.

I would like to be able to run my ViewModel integration tests with actual services, not with mocked instances.

Is there Unit / Integration asynchronous testing support for WPF applications?

Update:

At the end of the day, my solution combined the offers of ktutnik and Alex Paven. I wrote a tiny helper class that adds syntactic sugar:

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

Here's a test case example combined with using 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 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");
        }
    });
}
+3
2

, .

, . 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

-

resetEvent.Set();

, , ,

+3

Reactive Extensions, .Net Framework 4, ; 3.5 Silverlight. , . . .

+1

Source: https://habr.com/ru/post/1761372/


All Articles