Intro
It is absolutely essential to protect our code base from breaking changes. “We must protect this house!” One of the most important tests that need to be performed in software is testing user confirmations. Many professional debuggerers only know how to test this by launching the actual application to display a confirmation dialog. There is a better way of testing this part of an application. It’s called unit testing. Unit tests can not only test business logic. Unit tests can also target user-interaction logic such as confirmation dialogs. There are multiple ways to unit test a user-confirmation dialog.
One method is to use an interface that exposes an event. When the event on that interface is raised, the user-interaction logic gets invoked. I wrote an article about this implementation here. The “UserInteraction” interface can be leveraged from Bizmonger.Patterns on Nuget.
Testing with Messages
An alternative approach to unit testing a confirmation dialog without using an interface would be leveraging a Publisher/Subscribe model. Specifically, we rely on a messaging system. Using this approach, a mediator has two responsibilities. The first responsibility that the mediator has is to route the subscriptions of subscribers to their corresponding publishers. The other responsibility is to route the messages of publishers to their corresponding subscribers.
Consider the following code:
ViewModel.internal
using static Bizmonger.Patterns.MessageBus; void Process(bool isSuccessful) { SubscribeFirstPublication(Messages.REQUEST_CONTINUE_LOGGING_RESPONSE, OnConfirmation); Publish(Messages.REQUEST_CONTINUE_LOGGING, isSuccessful); } void OnConfirmation(object obj) { var continueLogging = (bool)obj; if (!continueLogging) return; ContinueLogging(); }
The above logic publishes a request to continue with an operation. It is important to realize that a subscription to a response of that request must be registered first before publishing the request. I call this method of structuring code a “promise”. Hence, we promise to respond to a message.
View (Code-behind)
using static Bizmonger.Patterns.MessageBus; public partial class View : ContentPage { bool _continueLogging = false; public View() { InitializeComponent(); Subscribe(Messages.REQUEST_CONTINUE_LOGGING, async obj => { var status = (bool)obj ? "success" : "failure"; _continueLogging = await DisplayAlert("Confirmation", $"Confirm {status}?", "Ok", "Cancel"); Publish(Messages.REQUEST_CONTINUE_LOGGING_RESPONSE, _continueLogging); }); } }
The code above reflects the logic used to display a confirmation dialog. Within the constructor of our view, we subscribe to a confirmation message from the outside world. This message is “REQUEST_CONTINUE_LOGGING”. When this message comes in from the outside world, we display a confirmation dialog to our user asking if he/she would like to continue with the operation. We then publish the user’s response from the confirmation we displayed for the unknown subscribers to handle.
Unit Test
The following is a unit test that that handles the user confirmation:
[TestMethod] public void adding_success_updates_datapoints() { // Setup var databaseCreated = new MockDatabase() != null; var viewModel = new ViewModel(); Subscribe(Messages.REQUEST_CONTINUE_LOGGING, obj => Publish(Messages.REQUEST_CONTINUE_LOGGING_RESPONSE, true)); // Test viewModel.Success.Execute(null); // Verify var datapoint = viewModel.DataPoints.Single(); var expected = datapoint.Successes == 1 && datapoint.Failures == 0; Assert.IsTrue(expected); }
Observe how we subscribe to a request and then publish a response.
Conclusion
In conclusion, one of the most important tests that need to be performed in software is testing user confirmations. Many professional debuggerers only know how to test this by launching the actual application to display a confirmation dialog. There is a better way of testing this part of an application. It’s called unit testing. Unit tests can not only test business logic. Unit tests can also target user-interaction logic such as confirmation dialogs. There are multiple ways to unit test a user-confirmation dialog. I have documented these methods of testing user-interactions via interfaces (aka contracts) and also by messaging.
NOTE:
Scott Nimrod is fascinated with Software Craftsmanship.
He loves responding to feedback and encourages people to share his articles.
He can be reached at scott.nimrod @ bizmonger.net