Testing Messages and Modules

I am trying to find the best way to parse message boxes from my logic so that I can properly resolve it. Now I was wondering if this was enough if I just made a separate helper class (C #), which I can later delete for my post. For example:

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 every time I need to use the message box, I would just use messageboxHelper / msgBoxAlg (...) instead of messagebox.show (...). Using bool show, I could enable or disable it during testing.

I'm just wondering if this is right. By this I mean, is there an easier or better way to do it right? I can’t just turn off the mailboxes, they relay the "important" information to the user ("Do you want to close these windows?" YES / NO, etc.). Maybe I'm just not using proper software development, and should I separate my posts from my bussinesslogic anymore?

+8
c # unit-testing messagebox
source share
4 answers

Yes, that's right. But instead of a static class, you should implement IDialogService and introduce 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 of SomeClass you should enter the layout of the IDialogService object instead of the real one.

If you need to test more UI logic, consider a template

+29
source share

Look at inversion of control (IoC), the basic principle is that things that perform ect actions should be passed as an interface, then you use the IoC container to bind the interfaces to specific implementations for your application. To easily achieve this in your case, pass what the message boxes do as an interface, and in your unit test creat, a mock (false) version of this message service that does not show the message box

take a look at http://martinfowler.com/articles/injection.html for more information on IoC, my favorite container is Ninject (http://ninject.org)

+2
source share

Ideally, you want the code you tested with unit tests to be a logical and not a user interface. Therefore, the logic of your testing should not be displayed on the screen. If you want to test the user interface, I would suggest coded user interfaces .

Judging by your question, I would suggest that your code should not use MessageBox . Perhaps instead consider using a callback or an arbitrary Action or approaches mentioned by Luke McGregor and Sergey V.

+1
source share

"Unit test", in its exact meaning, is a test of atomic behavior. This is not the only type of code test you can do for your code. Specially for testing longer scripts with Yes / No dialogs that you mentioned, larger-scale code-driven tests are often more efficient than unit tests.

However, to be able to write them easier, it would be nice not only to create a special service, as Sergey mentioned, but also to make its calls asynchronous:

 public interface IDialogService { Task<bool> ShowYesNoMessageBox(...); ... } 

By wrapping messages in non-asynchronous service calls and mocking them, for longer scenarios you will start to contradict the Arrange-Act-Assert pattern, predicting the user's action before its actual action (making "Arrange" instead of "Act"), which can cause numerous problems when testing, especially if your tests are performed using BDD / SpecFlow. Making these asynchronous calls avoids such problems. See my blog article for more details and examples of larger tests using posts.

+1
source share

All Articles