Advice on Unit testing a Windows Forms application - c#

I have written a Windows Forms application and now I want to write some unit tests for it (not exactly test driven development seeing as I am writing the tests after I have developed but better late then never!) My question is that with such an application how do you go about writing the unit tests, given that nearly all of the methods and events are private? I have heard of NUnit Forms but I hear good and bad things about it, also there has been no real development on that project for a while so it looks abandoned. Also is it generally accepted that the project have have adequate unit testing in place if I wrote unit test cases for all of the events that a user would trigger by clicking/ pressing buttons, or would I have to go and write unit test cases for all methods and figure out a way to test my private methods?
EDIT: My business logic is seperated from my presentation logic, there is 1 or 2 public methods my business logic exposes so the form can access them, but what about all the private methods that are in the business logic?

The key to Unit Testing graphical applications is to make sure that all most all of the business logic is in a separate class and not in the code behind.
Design patterns like Model View Presenter and Model View Controller can help when designing such a system.
To give an example:
public partial class Form1 : Form, IMyView
{
MyPresenter Presenter;
public Form1()
{
InitializeComponent();
Presenter = new MyPresenter(this);
}
public string SomeData
{
get
{
throw new NotImplementedException();
}
set
{
MyTextBox.Text = value;
}
}
private void button1_Click(object sender, EventArgs e)
{
Presenter.ChangeData();
}
}
public interface IMyView
{
string SomeData { get; set; }
}
public class MyPresenter
{
private IMyView View { get; set; }
public MyPresenter(IMyView view)
{
View = view;
View.SomeData = "test string";
}
public void ChangeData()
{
View.SomeData = "Some changed data";
}
}
As you can see, the Form only has some infrastructure code to thy everything together. All your logic is inside your Presenter class which only knows about a View Interface.
If you want to unit test this you can use a Mocking tool like Rhino Mocks to mock the View interface and pass that to your presenter.
[TestMethod]
public void TestChangeData()
{
IMyView view = MockRepository.DynamickMock<IMyView>();
view.Stub(v => v.SomeData).PropertyBehavior();
MyPresenter presenter = new MyPresenter(view);
presenter.ChangeData();
Assert.AreEqual("Some changed data", view.SomeData);
}

The first thing I would do is to ensure that you have proper separation of your business logic from your form. Basically, using an MVC pattern. Then, you can easily test everything outside the form, as if the form didn't even exist.
Now, this could still leave some untested form-specific functionality. I.E., is the form wired-up to the service correctly? For this, then you could still consider something like NUnit Forms or another alternative.

Break out all business logic into a separate project and unit test that. Or at least move all logic from the forms into separate classes.

You have a few options.
Use a tool like Coded UI to test via your user interface. This isn't a great option, because it's slower than unit testing and the tests tend to be more brittle.
Separate your business logic from your presentation logic. If you have a lot of private methods performing business logic in your UI, you've tightly coupled your business logic to your presentation. Start identifying these and moving them out to separate classes with public interfaces that you can test. Read up on SOLID principles, which can help you keep your code loosely coupled and testable.

Unit testing the View is simple enough using approvaltests ( www.approvaltests.com or nuget). there is a video here: http://www.youtube.com/watch?v=hKeKBjoSfJ8
However, it also seems like you are worried about making a function default or public for the purposes of being able to test functionality.
These are usually referred to as seams; ways to get into your code for testing.
and they are good. Sometime people confuse private/public with security, and are afraid to turn a private function public, but reflection will call either, so it's not really secure. Other times people are worried about the API interface to a class. But this only matters if you have a public API, and if you have a winform app, it is probably meant to be the top level (no other consumers are calling it.)
You are the programmer, and as such can design your code to be easy to test. This usually means little more than changing a few methods public and creating a few connivence methods that allow dependences to be passed in.
For example:
buttonclick += (o,e)=> {/*somecode*/};
is very hard to test.
private void button1_Click(object sender, EventArgs e) {/*somecode*/}
still hard to test
public void button1_Click(object sender, EventArgs e) {/*somecode*/}
easier to test
private void button1_Click(object sender, EventArgs e) { DoSave();}
public void DoSave(){/*somecode*/}
Really easy to Test!
This goes double if you need some information from the event. ie.
public void ZoomInto(int x, int y)
is much easier to test that the corresponding mouse click event, and the passthrough call can still be a single ignorable line.

One may employ the MVVM (Model–View–ViewModel) pattern with Reactive.UI, to author testable WinForms code. To get the separation of concerns really need. See: Reactive.UI https://reactiveui.net/ The main downside of using Winforms / MVVM / Reactive.UI is that there are not a lot of examples of its use (for WinForms). The upside is that it is applicable to just about all desktop frameworks and languages. You learn it for one, but the principles apply for all. When you have lots of private methods, that's OK. IMHO: try to use public methods to begin a business process you want to test. You can use tell-don't-ask: https://martinfowler.com/bliki/TellDontAsk.html and still keep all those methods private.
One may also test the code by driving the UI but this is not so highly recommended, because the resultant tests are (1) very fragile, (2) harder to get working, and IMHO, (3) can't be written at the same level of fine granuality as pure code tests; (4) Finally: if you use a database, you will need to consider populating it with test data, and, because your database must be in a clean, well-defined state before each test, (5) your tests may run even slower than your thought as you reinitialize the data for each test.
Summary: Author your code with good SoC (e.g. by applying MVVM), then your code will have far better testability.

Related

Messagebox and Unit testing

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?
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.
Look into Inversion of Control (IoC), the basic principal is that things that perform actions ect should be passed in as an interface then you use a IoC container to bind interfaces to specific implementations for your app. To easily achieve this in your case pass the thing that does message boxes in as an interface and in your unit test creat a mock (fake) version of that message box service which does not show a message box
look at http://martinfowler.com/articles/injection.html for details on IoC, my favorite container is Ninject (http://ninject.org)
Ideally, you want the code your testing with Unit Tests to be logic and not UI. Therefore, the logic your testing shouldn't really be displaying a message box. If you are wanting to test the UI, then I would suggest Coded UI Tests.
Judging by your question, I would imagine your code shouldn't really be using a MessageBox. Perhaps instead consider using a callback or arbitrary Action, or the approaches mentioned by Luke McGregor and Sergey V.
"Unit test", in its exact meaning, is a test of atomic behavior. This is not the only kind of code-driven tests you can make for your code. Especially for testing longer scenarios with "Yes/No" dialogs you mention, larger-scale code-driven tests are often more effective than unit tests.
However to be able to write them easier, it would be good not only to create a special service as it was mentioned by Sergii, but also to make its calls asynchronous:
public interface IDialogService
{
Task<bool> ShowYesNoMessageBox(...);
...
}
By wrapping messageboxes in non-asynchronous service calls and mocking them, for longer scenarios you'll start to contradict "Arrange-Act-Assert" pattern by predicting user action before it actually happens (doing "Arrange" instead of "Act"), which can cause numerous problems in testing, especially if your tests are done using BDD/SpecFlow. Making these calls asynchronous allows to avoid such problems. See my blog article for details and samples of larger-scale tests with messageboxes.

Proper way for form events to reach into application

I have some debugging functions that I would like to refactor, but seeing as they are debugging functions, it seems like they would be less likely to follow proper design. They pretty much reach into the depths of the app to mess with things.
The main form of my app has a menu containing the debug functions, and I catch the events in the form code. Currently, the methods ask for a particular object in the application, if it's not null, and then mess with it. I'm trying to refactor so that I can remove the reference to this object everywhere, and use an interface for it instead (the interface is shared by many other objects which have no relation to the debugging features.)
As a simplified example, imagine I have this logic code:
public class Logic
{
public SpecificState SpecificState { get; private set; }
public IGenericState GenericState { get; private set; }
}
And this form code:
private void DebugMethod_Click(object sender, EventArgs e)
{
if (myLogic.SpecificState != null)
{
myLogic.SpecificState.MessWithStuff();
}
}
So I'm trying to get rid of the SpecificState reference. It's been eradicated from everywhere else in the app, but I can't think of how to rewrite the debug functions. Should they move their implementation into the Logic class? If so, what then? It would be a complete waste to put the many MessWithStuff methods into IGenericState as the other classes would all have empty implementations.
edit
Over the course of the application's life, many IGenericState instances come and go. It's a DFA / strategy pattern kind of thing. But only one implementation has debug functionality.
Aside: Is there another term for "debug" in this context, referring to test-only features? "Debug" usually just refers to the process of fixing things, so it's hard to search for this stuff.
Create a separate interface to hold the debug functions, such as:
public interface IDebugState
{
void ToggleDebugMode(bool enabled); // Or whatever your debug can do
}
You then have two choices, you can either inject IDebugState the same way you inject IGenericState, as in:
public class Logic
{
public IGenericState GenericState { get; private set; }
public IDebugState DebugState { get; private set; }
}
Or, if you're looking for a quicker solution, you can simply do an interface test in your debug-sensitive methods:
private void DebugMethod_Click(object sender, EventArgs e)
{
var debugState = myLogic.GenericState as IDebugState;
if (debugState != null)
debugState.ToggleDebugMode(true);
}
This conforms just fine with DI principles because you're not actually creating any dependency here, just testing to see if you already have one - and you're still relying on abstractions over concretions.
Internally, of course, you still have your SpecificState implementing both IGenericState and IDebugState, so there's only ever one instance - but that's up to your IoC container, none of your dependent classes need know about it.
I'd highly recommend reading Ninject's walkthrough of dependency injection (be sure to read through the entire tutorial). I know this may seem like a strange recommendation given your question; however, I think this will save you a lot of time in the long run and keep your code cleaner.
Your debug code seems to depend on SpecificState; therefore, I would expect that your debug menu items would ask the DI container for their dependencies, or a provider that can return the dependency or null. If you're already working on refactoring to include DI, then providing your debug menu items with the proper internal bits of your application as dependencies (via the DI container) seems to be an appropriate way to achieve that without breaking solid design principles. So, for instance:
public sealed class DebugMenuItem : ToolStripMenuItem
{
private SpecificStateProvider _prov;
public DebugMenuItem(SpecificStateProvider prov) : base("Debug Item")
{
_prov = prov;
}
// other stuff here
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
SpecificState state = _prov.GetState();
if(state != null)
state.MessWithStuff();
}
}
This assumes that an instance of SpecificState isn't always available, and needs to be accessed through a provider that may return null. By the way, this technique does have the added benefit of fewer event handlers in your form.
As an aside, I'd recommend against violating design principles for the sake of debugging, and have your debug "muck with stuff" methods interact with your internal classes the same way any other piece of code must - by its interface "contract". You'll save yourself a headache =)
I'd be inclined to look at dependency injection and decorators for relatively large apps, as FMM has suggested, but for smaller apps you could make a relatively easy extension to your existing code.
I assume that you push an instance of Logic down to the parts of your app somehow - either though static classes or fields or by passing into the constructor.
I would then extend Logic with this interface:
public interface ILogicDebugger
{
IDisposable PublishDebugger<T>(T debugger);
T GetFirstOrDefaultDebugger<T>();
IEnumerable<T> GetAllDebuggers<T>();
void CallDebuggers<T>(Action<T> call);
}
Then deep down inside your code some class that you want to debug would call this code:
var subscription =
logic.PublishDebugger(new MessWithStuffHere(/* with params */));
Now in your top-level code you can call something like this:
var debugger = logic.GetFirstOrDefaultDebugger<MessWithStuffHere>();
if (debugger != null)
{
debugger.Execute();
}
A shorter way to call methods on your debug class would be to use CallDebuggers like this:
logic.CallDebuggers<MessWithStuffHere>(x => x.Execute());
Back, deep down in your code, when your class that you're debugging is about to go out of scope, you would call this code to remove its debugger:
subscription.Dispose();
Does that work for you?

when should i create a private method in c#

Since following DI and TDD, I'm bit confused as to when should I create a private method. Could you please tell me what should be the rules of thumb to be considered while making a method private keeping testability and Dependency injection in mind?
I believe an example might help here:
Assume I have an interface with 3 methods like the following:
public interface IWordFrequencyAnalyzer
{
int CalculateHighestFrequency(string forText);
int CalculateFrequencyForWord(string text, string word);
IList<IWordFrequency> CalculateMostFrequentNWords(
string text, int n);
}
Now, I can write a class which can implement a private method which takes a string and can compute the frequency of words in it, and later in each public method I can do a manipulation according to it's requirement.In this case I'll be able to test the contract.
OR
I can extract that private method into a seperate class say something like WordProcessor which implements IWordProcessor, with a single public method which splits the sentence into words and pass it as dependency to the implementation of IWordFrequencyAnalyzer. This way the implementation of splitting the words is testable as well.
Which approach will you suggest?
Thanks,
-Mike
Since getting more into DI and TDD I ended up using private methods less and less, but the reason was not because I needed them to be public for tests. It's more because, as a by-product of using DI, I'm learning more about applying the SOLID principles to my code and this (in turn) is leading me to write classes with less methods overall and almost none private.
So, let's say you have a piece of your code you're using throughout various methods of your class. You know about DRY and you refactor it out to a private method and all's good. Except that often you realize you can generalize what that private method does and inject that functionality as an external dependency of the class: this way, you can test it and mock it, sure, but above all you can reuse what that method does even in other classes or other projects if needs be. Moving it out of the original class is an application of the single responsibility principle.
As I said this change in the way I code is not directly depending on the fact I use TDD or DI, but it's a by-product of the principles TDD encourages me to enforce and of the convenience that DI containers provide in composing the many small classes that result from this approach.
EDIT: The second approach in the example you added to your question is a good example of what I was talking about. The fact your new WordProcessor class is now testable is a plus, but the fact it's now composable and reusable is the real benefit.
Your methods should be private unless they need to be public for your application, not your test.
Generally you shouldn't make things public just to support unit testing (internal might help there). And in that case, you should generally still be testing public interfaces, not private details of the class, which are much more likely to change and break your test.
If you have access to a copy, Roy Osherove's "The Art Of Unit Testing" addresses this issue pretty well
You specific methods as private when they are only used internally by the object, normally called from other methods, some of which will be public or protected. You are more likely to create private methods as a result of following the DRY (Don't Repeat Yourself) principles. In that scenario you'd extract some common code used by several methods into a private method called by those methods.
Making every method of a class public and write a unit test for every method on such class will create a maintenance nightmare quickly, because you will have to change your tests for every little refactoring in your production code. You want to test the behavior of the class itself and for this you don't need every method to be public.
You should keep your methods private always when it is possible. Don't change them to public only for unit tests. When you see that it is hard to test it then consider to change a little bit architecture of your class. From my experience usually when I needed to test private method the class had wrong responsibilities so I changed it.
The Single Responsibility Policy will help you in this matter. Consider this example:
internal class Boss
{
private bool _notEnoughStaff;
private IList<Employee> _staff;
public Boss(bool notEnoughStaff)
{
_notEnoughStaff = notEnoughStaff;
}
public void GiveOrders()
{
if (_notEnoughStaff)
HireStaff();
foreach (Employee employee in _staff)
{
employee.DoWork();
}
}
private void HireStaff()
{
_staff.Add(new Employee());
}
}
public class Employee
{
public void DoWork()
{
}
}
In this case I see not one but two responsibilities: The Boss delegates work AND hire new staff. In this example, I would always extract the private method HireStaff to a new class (let's call it HR), and inject this into the Boss class.
This is a very simplified example, but as you get more and more experienced in the TDD way of thinking, you will find that not many private methods have legitimacy.
Regards,
Morten

First Unit Test (VS2010 C#)

This is my first encounter with unit testing and I am trying to understand how can this concept be used on a simple date validation.
The user can select a ToDate that represents the date until a payment can be made. If our date is not valid the payment cant be made.
private void CheckToDate(DateTime ToDate)
{
if (Manager.MaxToDate < ToDate.Year)
//show a custom message
}
How can unit tests be used in this case?
Regards,
Alex
Thanks for your answers:
As suggested by many of you I will split the function and separate the validation from the message display and use unit tests just for this.
public bool IsDateValid(DateTime toDate)
{
return (Manager.MaxToDate < toDate.Year);
}
Yes it is possible. But unit testing changes design of your class. To make possible unit testing of this code, you should made following changes:
Make your method public. (It is possible to make it protected, but for simplicity make it public).
Extract all external dependencies of this method to interface, so you can mock them. Then you can use some mocking library (moq, Rhino.Mocks) to simulate real dependencies and write asserts.
Write test.
Here is sample code.
The class under test:
public class ClassUnderTest
{
public IManager Manager {get;set;}
public IMessanger Messanger {get;set}
public ClassUnderTest (IManager manager, IMessanger messanger)
{
Manager = manager;
Messanger = messanger;
}
private void CheckToDate(DateTime ToDate)
{
if (Manager.MaxToDate < ToDate.Year)
//show a custom message
Messanger.ShowMessage('message');
}
}
Test:
[TestFixture]
public class Tester
{
public void MessageIsShownWhenDateIsLowerThanMaxDate()
{
//SetUp
var manager = new Mock<IManager>();
var messanger = new Mock<IMessanger>();
var maxDate = DateTime.Now;
manager.Setup(m => m.MaxToDate).Returns(maxDate);
var cut = new ClassUnderTest (manager.Object, messanger.Object);
//Act
cut.CheckToDate();
//Assert
messanger.Verify(foo => foo.ShowMessage("message"), Times.AtLeastOnce())
}
}
Design change, introduced by test gives you nice decoupling in system. And tests could be written for specific classes, when external dependencies are event not written.
Sure thing :-) Detecting that the custom message is shown can require a little trick (I assume you mean a messagebox displayed on a GUI, but the idea is the same even if the message is displayed differently).
You can't detect mssage boxes from unit tests, neither you want to launch the whole GUI environment from your unit tests. The easiest way to work around this is to hide the actual code displaying a message box in a separate method, ideally in a distinct interface. Then you can inject a mock implementation of this interface for your unit tests. This mock does not display anything, just records the message passed to it, so you can check it in your unit test.
The other issue is that your method is private. Check first where it is called from, and whether it can be called via a public method without too much complication. If not, you may need to make it (temporarily) public to enable unit testing. Note that the need to unit test private methods is usually a design smell: your class may be trying to do too much, taking on too many distinct responsibilities. You may be able to extract some of its functionality into a distinct class, where it becomes public, thus directly unit testable. But first you need to have those unit tests, to ensure you are not breaking anything when refactoring.
You then need to set up the Manager.MaxToDate prior to the test with a suitable date, and call CheckToDate with various parameters, check that the result is as expected.
The recommended reading for similar tricks and more is Working Effectively with Legacy Code.
Unit testing is best done on the public interface of your classes. So, I'd suggest you either make this public, or look to test it indirectly (through the public methods you do expose).
As for "Is it possible to create unit tests for something like this?", it depends on how pure you want to be on the concept of Unit Tests, how user-dependent you want them to be, and what exactly //show a custom message does.
How pure do you want your unit tests to be? If you don't care if they are dirty hacks, then you can use reflections to expose the private method to your unit tests, and just call it directly. This is in general a bad practice, though, because your private functions by definition are subject to change. Otherwise you'd just make them public.
If //show a custom message prints to the console, then you can make silent-running tests fairly easily. If you actually want to verify the output, you'd have to hook into your Console.Out, so you can see what got printed, and add corresponding assertions.
If //show a custom message uses MessageBox.Show, then you may have to make a UI Automated Test to be able to test this. Your tests will not be able to run silently in the background, and will break if you're moving your mouse while the test is running.
If you don't want to make a UI Automated Test just to test the logic of this class, the best way I know of is to modify your class to use dependency injection. Encapsulate all of the actual output code (MessageBox.Show) into another class, abstract it via an interface or abstract base class, and make it so your original class takes a reference to the abstract type. This way you can inject a mock in your tests, and it won't actually output to the screen.
public interface INotification
{
void ShowMessage(string message);
}
public class MessageBoxNotification : INotification
{
public void ShowMessage(string message)
{
MessageBox.Show(message);
}
}
public class MyClass
{
private INotification notification;
public MyClass(INotification notification)
{
this.notification = notification;
}
public void SomeFunction(int someValue)
{
// Replace with whatever your actual code is...
ToDate toDate = new SomeOtherClass().SomeOtherFunction(someValue);
CheckToDate(toDate);
}
private void CheckToDate(DateTime ToDate)
{
if (Manager.MaxToDate < ToDate.Year)
notification.Show("toDate, too late!: " + toDate.ToString());
}
}
Your unit test would make it's own custom INotification class, pass it to the constructor of MyClass, and invoke the SomeFunction method.
You'll probably want to abstract things like Manager, and the classes involve in computing ToDate in a similar way.
Introducing unit testing often makes you think more actively about code design (if you didn't already). Your case is interesting in this aspect. It is tricky to test, and one reason for that is that it does two different things:
It validates the date
It reacts on a failed validation by showing a message
A well-crafted method does only one thing. So, I would recommend refactoring the code a bit so that you get a validation method that does nothing but validates. This method will be very simple to test:
public bool IsDateValid(DateTime toDate)
{
// just guessing on the rules here...
return (Manager.MaxToDate >= toDate.Year);
}
This will also make the validation code far more reusable, since it moves the desicion on how to treat the result to the calling code.

Please tell me a architecture to use in a Windows Form project

I want an architecture to make my UI interact with the database without writing excess code for the UI...i.e. the code behind...
Use the Business Object / User Interface / Business Logic / Data Access architecture.
BO------UI
| |
--------BL
| |
--------DA
A starting point is to define some simple rules of thumb. A good rule of thumb is to have as little code as possible in the Form class. All code in the Form class should be basic UI mapping really.
I personally like using the DAO pattern for organising my database access logic. This pattern neatly encapsulates the code accessing & storing the data, so it can easily be switched and changed. Depending on the complexity of the database, I will normally have 1 DAO per table but for simple databases maybe even just 1 DAO per database.
MVC is a popular way to seperate presentation and other logic as well, but may be overkill for a simple project. Use cases are also a good way to encapsulate logic and seperate it out from the form.
An example of what a basic framework may look like, see below (note: not complete! read the full DAO article to properly implement it). The point of this code is to show that no database logic is in the Form class, it is a simple one-liner when the button is clicked (or whatever) mapping the UI to an action. If you decided to swap from database storage to file storage, it would not be hard to write a FileMyDAO : IMyDAO class and then have the factory return this instead. Notice that none of the UI code changes if you do this!
public interface IMyDAO
{
void InsertData(int data);
}
public class SqlMyDAO : IMyDAO
{
public void InsertData(int data) { throw new NotImplementedException(); }
}
public class DAOFactory
{
public static IMyDAO GetMyDAO() { return new SqlMyDAO(); }
}
public class MyForm : Form
{
private void Button_Click(object sender, EventArgs e)
{
DAOFactory.GetMyDAO().InsertData(123);
}
}
Data Binding is something that you should look into. This will lead you onto more studies but you will certainly get to know the staff you need.
buddy you can use the premitive architecture:
BusinessObjectLayer
BusinessLogicLayer
DataAccessLayer
UILayer
There are already developed free architectural frameworks there waiting to be used.. check..
Nido framework - more flexible, but only for your back end architecture
or
Rocket framework

Categories