Library tutorials & articles
Test-Driven Development in .NET
- Introduction & Unit Tests
- The NUnit Testing Framework
- Running Your Tests & Doing TDD
- Using Mock Objects - DotNetMock
- Conclusion
The NUnit Testing Framework
NUnit 2.0 is a radical departure from its ancestors. Those systems provided base classes from which you derived your test classes. There simply was no other way to do it. Unfortunately, they also imposed certain restrictions on the development of test code because many languages (like Java and C#) only allow single inheritance. This meant that refactoring test code was difficult without introducing complicated inheritance hierarchies. .NET introduced a new concept to programming that solves this problem: attributes. Attributes allow you to add metadata to your code. They typically don't affect the running code itself, but instead provide extra information about the code you write. Attributes are most often used to document your code, but they can also be used to provide information about a .NET assembly to a program that has never seen the assembly before. This is exactly how NUnit 2.0 works. The Test Runner application scans your compiled code looking for attributes that tell it which classes and methods are tests. It then uses reflection to execute those methods. You don't have to derive your test classes from a common base class. You just have to use the right attributes. NUNit provides a variety of attributes that you use when creating unit tests. They are used to define test fixtures, test methods, setup and teardown methods. There are also attributes for indicating expected exceptions or to cause a test to be skipped.
TestFixture Attribute
The TestFixture attribute is used to indicate that a class contains test methods. When you attach this attribute to a class in your project, the Test Runner application will scan it for test methods. The following code illustrates the usage of this attribute. (All of the code in this article is in C#, but NUnit will work with any .NET language, including VB.NET. See the NUnit documentation for additional information.)
namespace UnitTestingExamples
{
using System;
using NUnit.Framework;
[TestFixture]
public class SomeTests
{
}
}
The only restrictions on classes that use the TestFixture attribute are that they must have a public default constructor (or no constructor which is the same thing).
Test Attribute
The Test attribute is used to indicate that a method within a test fixture should be run by the Test Runner application. The method must be public, return void, and take no parameters or it will not be shown in the Test Runner GUI and will not be run when the Test Fixture is run. The following code illustrates the use of this attribute:
namespace UnitTestingExamples
{
using System;
using NUnit.Framework;
[TestFixture]
public class SomeTests
{
[Test]
public void TestOne()
{
// Do something...
}
}
}
SetUp & Teardown Attributes
Sometimes when you are putting together Unit Tests, you have to do a number of things, before or after each test. You could create a private method and call it from each and every test method, or you could just use the Setup and Teardown attributes. These attributes indicate that a method should be executed before ( SetUp ) or after ( Teardown ) every test method in the Test Fixture. The most common use for these attributes is when you need to create dependent objects (e.g., database connections, etc.). This example shows the usage of these attributes:
namespace UnitTestingExamples
{
using System;
using NUnit.Framework;
[TestFixture]
public class SomeTests
{
private int _someValue;
[SetUp]
public void Setup()
{
_someValue = 5;
}
[TearDown]
public void TearDown()
{
_someValue = 0;
}
[Test]
public void TestOne()
{
// Do something...
}
}
}
Expected Exception Attribute
It is also not uncommon to have a situation where you actually want to ensure that an exception occurs. You could, of course, create a big try..catch statement to set a boolean, but that is a bit hack-ish. Instead, you should use the ExpectedException attribute, as shown in the following example:
namespace UnitTestingExamples
{
using System;
using NUnit.Framework;
[TestFixture]
public class SomeTests
{
[Test]
[ExpectedException(typeof(InvalidOperationException))]
public void TestOne()
{
// Do something that throws an
// InvalidOperationException
}
}
}
When this code runs, the test will pass only if an exception of type InvalidOperationException is thrown. You can stack these attributes up if you need to expect more than one kinds of exception, but you probably should it when possible. A test should test only one thing. Also, be aware that this attribute is not aware of inheritance. In other words, if in the example above the code had thrown an exception that derived from InvalidOperationException , the test would have failed. You must be very explicit when you use this attribute.
Ignore Attribute
You probably won't use this attribute very often, but when you need it, you'll be glad it's there. If you need to indicate that a test should not be run, use the Ignore attribute as follows:
namespace UnitTestingExamples
{
using System;
using NUnit.Framework;
[TestFixture]
public class SomeTests
{
[Test]
[Ignore("We're skipping this one for now.")]
public void TestOne()
{
// Do something...
}
}
}
If you feel the need to temporarily comment out a test, use this instead. It lets you keep the test in your arsenal and it will continually remind you in the test runner output.
The NUnit Assertion Class
In addition to the attributes used to identify the tests in your code, NUnit also provides you a very important class you need to know about. The Assertion class provides a variety of static methods you can use in your test methods to actually test that what has happened is what you wanted to happen. The following sample shows what I mean:
namespace UnitTestingExamples
{
using System;
using NUnit.Framework;
[TestFixture]
public class SomeTests
{
[Test]
public void TestOne()
{
int i = 4;
Assertion.AssertEquals( 4, i );
}
}
}
(I know that isn't the most relevant bit of code, but it shows what I mean.)
Related articles
Related discussion
-
hey developers out there
by pitsophera (0 replies)
-
How can i develop opc server using .net?
by vairajaig (1 replies)
-
Creating a Windows Service in VB.NET
by davidvanr (108 replies)
-
High-Performance .NET Application Development & Architecture
by Manjot Bawa (0 replies)
-
An Introduction to VB.NET and Database Programming
by carlosmen (14 replies)
Related podcasts
-
The Past, Present and Future of .NET Unit Testing Frameworks
Scott gets a rare chance to sit down in person with developers from three .NET Unit Testing Frameworks. Charlie Poole from NUnit, Jeff Brown from MbUnit, Brad Wilson from xUnit.NET as well as Roy Osherove, the author of the upcoming "Art of Unit Testing."
Events coming up
-
Nov
18
15 Minutes of Fame
Dresher, United States
This is a yearly tradition. We select 10 of the favorite speakers from monthly meetings, code camps, and hands on labs. Each one does a 15 minute talk on their favorite .NET technology. This is our 10th anniversary so we plan a gala event with special prizes and refreshments.
Well explained. More about TDD using C# can be found here Link Text
!--removed tag-->Hello, would it be possible to post all of the code regarding the "Using Mock Objects - DotNetMock" article. The page outlines the process and most of the code, but it'd be great to see the UI that is actually being tested against the mocked version - i.e. it is slightly confusing about where the line is drawn on how much of the actual UI is being tested and being able to execute the real code against the mocked code would clarify how the view and the controller interact.
Many thanks
This thread is for discussions of Test-Driven Development in .NET.