Messagebox and Unit testing

Enthusiastic Programmer picture Enthusiastic Programmer · Dec 19, 2011 · Viewed 15k times · Source

I'm trying to find the best way to uncouple messageboxes from my logic so I can properly unittest it. Now I was wondering if it would be enough if I just made a seperate helper class (C#) which I can stub later for my messagebox. For instance:

static class messageBoxHelper
{
    public static void msgBoxAlg(string message, string title, MessageBoxButtons   buttons, MessageBoxIcon icons, bool show)
    {
        if (show)
        {
            MessageBox.Show(message, title, buttons, icons);
        }
 }

Then everytime I'd need to use a messagebox i'd just use messageboxHelper/msgBoxAlg(...) instead of messagebox.show(...). Using the bool show I could enable or disable it during testing.

I'm just wondering if this is the "right way". By which I mean, is there an easier or better way to do this properly? I can't just ditch the messageboxes, they relay "vital" info to the user ("Do you want to close this windows?" YES/NO etc.). It could also just be I'm not using proper software engineering, and I should decouple my messageboxes from my bussinesslogic more?

Answer

Sergii Vashchyshchuk picture Sergii Vashchyshchuk · Dec 19, 2011

Yes, it is right way. But instead of static class, you should implement IDialogService and inject it into classes that should display dialogs:

public interface IDialogService
{
    void ShowMessageBox(...);

    ...
}

public class SomeClass
{
    private IDialogService dialogService;

    public SomeClass(IDialogService dialogService)
    {
       this.dialogService = dialogService;
    }

    public void SomeLogic()
    {
        ...
        if (ok)
        {
            this.dialogService.ShowMessageBox("SUCCESS", ...);
        }
        else
        {
            this.dialogService.ShowMessageBox("SHIT HAPPENS...", ...);
        }
    }
}

During testing the SomeClass you should inject mock object of the IDialogService instead of real one.

If you need to test more UI logic, consider to use MVVM pattern.