Alright.
So I figure it’s about time I get into unit testing, since everyone’s been banging on about it for long enough. I’ve installed NUnit and gone through a few “intro to unit testing” type tutorials.
I’m currently putting together a small framework to help with the rebuild of one of our web apps, so I’ve created a VS2008 project for my framework and I want to unit test it as I go.
How on earth do I go about unit testing the WebControls? The methods are all protected or private, and since it’s a framework, there isn’t much else but WebControls.
Any pointers?
Burns
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can do model-view-controller or model-view-presenter type architectures without using a full blown framework. You already found out that unit-testing ui-components is difficult. There are ways around that but you probably don’t want to go that route. Usually this will make your tests very hard to maintain, more maintenance nightmare’s is something programmers can do without 🙂
Try to separate out the functionality you want to test in a “controller” or “presenter” class. Then test that class. To make it more testable you can hide the usercontrol class (the view) behind an interface and make the controller or presenter talk to the view through the interface. That way you can mock up the view in your tests.
I know this sounds like a lot of work and it seems like a workaround but if you get used to this it’s a realy nice architecture that makes it far easier to change ui behaviour. You can always start using a “real” mvc framework when you realy need it 🙂
Method 2
Ues the assembly:InternalsVisibleTo attribute and you’ll be able to access those private members.
Put it in your webcontrol project’s AssemblyInfo.cs (under Properties node)
[assembly:InternalsVisibleTo("YourTestProjectName")]
Method 3
You have found the biggest pain point of ASP.NET. As far as sealed, private classes that hinder unit testing.
This is the main reason that TDD people will use a MVC framework (ASP.NET MVC, Castle MonoRail) as it provides a clear seperation from your view templates and your controller logic. The controllers are fully testable.
Method 4
You could also look at testing components through the browser as a user would see them using a testing framework such as WebAii. I’ve seen it work and its pretty cool. I’ve also been told you can plug it into automated builds but I’ve not seen that as of yet.
Hope it helps …
Method 5
This is an old article by now, but I was using NUnitASP to write nunit tests for asp.net WebControls in 2004. That article gives a detailed example of testing a simple control using their concept of creating a corresponding “Tester” class that encapsulates the details of your control from you tests. The Tester can (should) also be in the same assembly as your control so can share some things between them (e.g. utility functions, constants, etc.).
I used the technique (and others use variants of the technique) still today to test very sophisticated controls.
I hope that is helpful.
Method 6
The MVC framework mentioned above is the best way to test what the control does. However testing how it works is a bit different.
This is totally off the cuff but you could make the user control expose some protected methods and properties to return validation information and then have a testing user control inherit it. That control could populate fields, press buttons and what not. Kind of messy but it could work.
Method 7
You can also take a look at this Rhino Igloo framework. It is a compromised MVC framework for WebForms.
Method 8
Ivonna
can test WebControls in isolation, within the Asp.Net context
Just call session.GetControl(“Path.ascx”) and verify that it has all necessary properties.
Method 9
You test them like this:
[Test]
public void ConditionQueryBuilderTest_RendersProperHtml()
{
var sw = new StringWriter();
var queryBuilder = new ConditionQueryBuilderStub
{
ID = "UnitTestbuilder",
QueryBuilderURL = @"SomeAspxPageSomeWebMethod",
ResetQueryBuilderURL = @"SomeAspxPageOnQueryBuilderReset",
FilterValuesCollection = new Dictionary<int, string> { {15, "Some Condition"}}
};
queryBuilder.RenderAllContents(new HtmlTextWriter(sw));
AppendLog(sw.ToString());
Assert.AreEqual(ExpectedHtml, sw.ToString()); // ExpectedHTML is the raw expected HTML
}
Here is my stub:
internal class ConditionQueryBuilderStub : ConditionQueryBuilder // ConditionQueryBuilder is a WebControl
{
internal void RenderAllContents(HtmlTextWriter writer)
{
RenderContents(writer);
}
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0