Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Introduction to unit testing in .NET

DZone's Guide to

Introduction to unit testing in .NET

· Agile Zone
Free Resource

See how three solutions work together to help your teams have the tools they need to deliver quality software quickly. Brought to you in partnership with CA Technologies

Unit testing is a way for the programmer to make sure that the code that is written is fully functional and works the way it is supposed to work. Unlike the standard testing method, when a piece of code is ran an the developer or tester manually feeds the values, unit tests can test specific methods/functions (or any other code elements) by providing the test data in code.

One of the fundamental principles of unit testing is to write tests first, and then write the simplest code that will make the test pass. I generally work a bit different – I write some simple code first, and then create the unit tests based on the possible situations. But this is a matter of personal choice and if you working the other way around, it is not a problem.

So let’s start with the code. I have a sample test application and a sample class, that has the contents outlined below:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Sandbox{    class Some    {        public string GetTheValue(string a, int x)        {            return a + x.ToString();        }        public string SampleString(string b, string c)        {            return b + c;        }    }}

Here I have two functions, both returning strings, but one accepting string and int parameters, while the other one accepts two string parameters. Now, to create unit tests for the functions, right click on the function declaration and select "Create Unit Tests..."

A window will appear, where you can select the classes, methods, functions and properties from the current class (as well as from other classes) that you want to use to create unit tests for.

In the image you can see that I only selected SampleString as the tested object. However, I can as well select both functions in the class. Once done, at the bottom there is a “Output project” dropdown menu, where you can select the targeted programming language for the unit tests. Since my main project is written in C#, I will also create a C# test project.

When asked for a name, type any name you want, as long as it is supported by the IDE. I named my test project MyTest.

Now, you can see that there is an additional project added to your solution:

It only has one active class called SomeTest.cs – it is the actual testing class for the existing Some.cs class in the main project. If you open it, you will see some automatically generated code. After a cleanup (for now I am not focusing on some of the details), the code should look similar to this:

using Sandbox;using Microsoft.VisualStudio.TestTools.UnitTesting;using System;namespace MyTest{    [TestClass()]    public class SomeTest    {        [TestMethod()]        public void SampleStringTest()        {            Some target = new Some(); // TODO: Initialize to an appropriate value            string b = string.Empty; // TODO: Initialize to an appropriate value            string c = string.Empty; // TODO: Initialize to an appropriate value            string expected = string.Empty; // TODO: Initialize to an appropriate value            string actual;            actual = target.SampleString(b, c);            Assert.AreEqual(expected, actual);            Assert.Inconclusive("Verify the correctness of this test method.");        }        [TestMethod()]        public void GetTheValueTest()        {            Some target = new Some(); // TODO: Initialize to an appropriate value            string a = string.Empty; // TODO: Initialize to an appropriate value            int x = 0; // TODO: Initialize to an appropriate value            string expected = string.Empty; // TODO: Initialize to an appropriate value            string actual;            actual = target.GetTheValue(a, x);            Assert.AreEqual(expected, actual);            Assert.Inconclusive("Verify the correctness of this test method.");        }    }}

One of the distinct elements that you will notice first if the presence of test attributes: [TestClass()] and [TestMethod()] – these basically determine what is tested.  You can see that the test class is practically an identic copy of the Some class, however, the methods are structured a bit different. First of all, those don’t have input parameters and are of type void.

This is because tests are used to try the working mechanism of a unit. Therefore, the verification isn’t returning results but rather just executes a set of actions.
Let’s start with SampleStringTest. Inside this method, I am instantiating the Some class and then creating two string variables, that are the parameters passed to the initial function. I am also setting their values, as the test will be performed against them. The expected variable is the result that the developer expects to get when the function is executed (the returned value). The actual variable stores the value returned after the execution.

There is also the Assert.AreEqual method that checks whether the expected value is the same as the returned one. If it is, then the test passes. If it is not, the test fails.

By default, the values specified for the variables are null. I am going to change this. For the same SampleStringTest method I am going to use this code:

[TestMethod()]public void SampleStringTest(){    Some target = new Some(); // TODO: Initialize to an appropriate value    string b = "Unit"; // TODO: Initialize to an appropriate value    string c = " Test"; // TODO: Initialize to an appropriate value    string expected = "Unit Test"; // TODO: Initialize to an appropriate value    string actual;    actual = target.SampleString(b, c);    Assert.AreEqual(expected, actual);}

Notice that I also removed the Assert.Incoclusive method call. It is generally used to show that the state of the test cannot be determined. In this case, I only want to see whether it fails or not. I also specified some test values and the expected value. This test should pass, since I provided correct test values and a correct expected value.

In the Test Tools toolbar, click the “Run Tests in Current Context” button, while your cursor is positioned inside the SampleStringTest method:

Now you should see the Test Results dialog on the bottom:

As you see, the test passed. Try changing the expected value, but leave the passed values intact. Once ran, the test will inevitably fail:

The same procedure that was applied to the SampleStringTest method can be applied to another test method as well.

In this article I showed the very basics of unit testing, the top of the iceberg, if you want to call it so. There is much more about it, but this is what you need to know to get started. This is a much more reliable method to test the existing code, rather than try and break the program by using manual value input. This probably doesn’t make much difference when working with string concatenation, but it eventually helps a lot when working with complex data acquisition and manipulation.

Discover how TDM Is Essential To Achieving Quality At Speed For Agile, DevOps, And Continuous Delivery. Brought to you in partnership with CA Technologies

Topics:
dotnet ,tests ,c-sharp ,unit

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}