Unit Testing a User Interaction

 

Introduction

I have yet to sit-in on a software development user-group presentation on TDD and have the presenter answer my question on the following:

How do I unit test a user interaction (i.e. confirmation dialog)?

This question was answered for me several years ago when I studied Prism. Prism is a WPF framework for building large enterprise applications in which the framework focuses on building applications by using a modular approach.

Anyways, I learned their pattern and practiced my understanding of it using my own implementation.

My solution for providing a unit testable interaction results from the following structures:

·         IConfirmationInteraction

·         ConfirmationInteraction

·         ConfirmationInteractionEventArgs

An Actual Unit Test

        [TestMethod]
        public void Example()
        {
            // Setup
            var viewModel = new ShortageViewModel();
            var dependencies = _mock.Dependencies();
            viewModel.Initialize(dependencies);

            dependencies.RefreshConfirmation = new ConfirmationInteraction(this, new ConfirmationInteractionEventArgs("some message", "Some Caption"));
            dependencies.RefreshConfirmation.RequestConfirmation += (s, e) => { return MessageBoxResult.Yes; };

            // Test
            viewModel.Load();
            viewModel.Await();

            var timeBeforeExtendedTimeline = viewModel.LastQueried;
            viewModel.Loaded = false;

            Thread.Sleep(MINIMUM_TIME_INTENSIVE_SLEEP);
            viewModel.RefreshCommand.Execute(null);
            viewModel.Await();

            // Verify
            var secondQueryRan = viewModel.LastQueried.Ticks.CompareTo(timeBeforeExtendedTimeline.Ticks) > 0;
            Assert.IsTrue(secondQueryRan);
        }

Notice how the RequestConfirmation event gives the client the opportunity to handle the actual implementation of the interaction as long as a result is returned.
This is the key element that is required for an interaction to be unit testable.

IConfirmationInteraction

using System.Windows;

namespace Bizmonger.Patterns
{
    public delegate MessageBoxResult RequestConfirmationHandler(object sender, ConfirmationInteractionEventArgs e);

    public interface IConfirmationInteraction
    {
        event RequestConfirmationHandler RequestConfirmation;
        MessageBoxResult Confirm();
    }
}

ConfirmationInteraction

using System.Windows;

namespace Bizmonger.Patterns
{
    public class ConfirmationInteraction : IConfirmationInteraction
    {
        #region Events
        public event RequestConfirmationHandler RequestConfirmation;
        #endregion

        #region Members
        object _sender = null;
        ConfirmationInteractionEventArgs _e = null;
        #endregion

        public ConfirmationInteraction(object sender, ConfirmationInteractionEventArgs e)
        {
            _sender = sender;
            _e = e;
        }

        public MessageBoxResult Confirm()
        {
            return RequestConfirmation(_sender, _e);
        }

        public MessageBoxResult Confirm(string message, string caption)
        {
            _e.Message = message;
            _e.Caption = caption;
            return RequestConfirmation(_sender, _e);
        }
    }
}

Calling Confirm() will launch the user interation.

ConfirmationInteractionEventArgs

using System;

namespace Bizmonger.Patterns
{
    public class ConfirmationInteractionEventArgs : EventArgs
    {
        public ConfirmationInteractionEventArgs() { }

        public ConfirmationInteractionEventArgs(string message, string caption, object parameter = null)
        {
            Message = message;
            Caption = caption;
            Parameter = parameter;
        }

        public string Message { get; set; }
        public string Caption { get; set; }
        public object Parameter { get; set; }
    }
}

This class provides the context of the message such as text content and a titlebar caption.

 

Conclusion

In conclusion, I have provided an implementation of the classes required to unit test a user interation. I welcome feedback.

Advertisements
1 comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: