Click here to Skip to main content
Click here to Skip to main content

Unit testing made easy Part 1: Repository Testing

, 13 Nov 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Step by step to your first unit testing

Introduction 

We are all familiar with a very common scenario while coding in a business application. In fact, this is the most frequent scenario where we want to save an object to the database. But how would we know that our code is functioning properly? Well there are many ways we could know. Some are good ways to follow and some are not. Let’s discuss using a scenario.

Example Scenario 

Suppose we want to save a Student object where the class will have Name, Phone, Email and Id. To save this object we should create a repository class named StudentRepository. In this class we will write our data saving codes.

Now there are some points I want to mention. It is good practice to create an interface for each of the repository class. It is a subset of Repository Pattern.

In our case, we should create IStudentRepository where we will define only Save method and make the StudentRepository class to implement this interface.

So, in summary we have three projects. Those are DataAccess, DataAccess.Contract, and Domain up to this state. Below are the class definitions and project architecture.

Entity Framework 

For implementing the database access code, we will not use traditional SqlClient library classes and don't write the traditional sql queries. Rather we will use the Entity Framework instead. Entity Framework (EF) is an object-relational mapper that enables .NET developers to work with relational data using domain-specific objects. It eliminates the need for most of the data-access code that developers usually need to write.

To use that framework in our project we need to install that. But where would we find that library? Well. Microsoft has developed an extension by which we can install, update and uninstall the external libraries to our project in a very easy way.  Below is how can we install the Entity Framework into our DataAccess Project..

Walkthrough: Install Entity Framework using Nuget 

  1. Right click on the reference option of the DataAccess project.
  2. Find the Entity Framework item (second in the below picture).
  3. Click the “install” button of that item.
  4. Click Accept when you are asked for the license agreement.
  5. After successful installation, you should see the green sign instead of the “install” button.

After installing the entity framework, we should create a class DataContext which will inherit DBContext class and we will map our class Student with the table name under OnModelCreating method. When the DataContext class is called for the first time, the Entity Framework will look for the Database and create the database by itself if that is not exists. Next, it will create the tables according to the instruction we gave in OnModelCreating method. From the below class, the system will create a database named MockingPractices.DataAccess.DataContext in .\SQLEXPRESS server (since we didn't give any connection string it will do it in the default server). And also the Student table is created.

The database

The DataContext class

namespace MockingPractices.DataAccess
{
    using System.Data.Entity;
    using MockingPractices.Domain;

    public class DataContext:DbContext 
    {
        public DbSet<Student> Students { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Student>().ToTable("Student");
            base.OnModelCreating(modelBuilder);
        }
    }
}

The IStudentRepository interface

namespace MockingPractices.DataAccess.Contract
{
    using MockingPractices.Domain;

    public interface IStudentRepository
    {
        int Save(Student student);
    }
}

The StudentRepository class

namespace MockingPractices.DataAccess
{
    using MockingPractices.DataAccess.Contract;
    using MockingPractices.Domain;

    public class StudentRepository : IStudentRepository
    {
        public int Save(Student student)
        {
            using (var context=new DataContext())
            {
                Student studentAdded = context.Students.Add(student);
                context.SaveChanges();
                return studentAdded.Id;
            }
        }
    }
}

Unit Testing 

Now we will find a way to test our codes. In a tradition way, we would have to create a Simple User Interface (might be Windows Forms Application) where there will be a button. If we click the button, we will create a student object and pass it to the repository method. Below is the scenario.

Class diagram

User Interface based testing architecture

But if we frequently change our code and need to test, then every time we must run the UI and hit the button for test. Things got worse if we need to test multiple scenarios for a single repository save method. So, what we can understand, we need a system which can manage automatically the calling of those methods. We don’t need to click and click the user interface for each change of the development code. Below may be one of the proposed architecture.

Automated testing architecture

This type of testing is named as automated unit testing and currently there is a couple of frameworks for this purpose. NUnit and Visual Studio’s internal Unit testing framework both are very common. Let’s use the second one in our solution. Below is how can you create a Unit Test project to your solution. If you still don't get the idea, don't worry. Just keep reading below. Smile | <img src= " />

Go to: Add New Project-->Visual C# --> Test --> Unit Test Project

Give appropriate name and then press OK button

Each of the unit testing frameworks has some classes by which the compiler understand to which classes should it run. This tag is TestClass for this and the required test methods must have TestMethod tag on top of it.

In our case, we can rename the default class to StudentRepositoryTest class and rename the given template method to SaveShouldReturnSavedId method.

So, the test method now looks like below.

Philosophy of the Unit Testing 

Let’s begin with a very sad but true scenario. Suppose one day you are in romantic mode, want to talk with your lover and you say “I Love You Jaan”. What do you expect to hear? We all expect “I love you too honey” or similar types of line in reply. But if your lover shouts at you then that shouting will definitely not be matched with your expectation. Am I right?

In programming world, we expect our method to work smoothly without any problem. We exactly know what to expect from a specific method. In our scenario, we expect our repository method to save the student object and returns us the saved id of that object. And we also know that Id must not be zero because our database’s primary key is auto incremented number and there is no way for the object to be saved in the id 0 row. So, our expectation is the returned value should be not equal to zero. Right? Make sense?

So how would we implement that scenario in our code?

There is a class named Assert made by Microsoft. Its duty is to match the expected value to the returned/actual value. If the expectation matches with the actual, it shows green but if the expectation mismatched, it shows red. So the code will looks like below.

namespace MockingPractices.DataAccess.Test
{
    using System.Transactions;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using MockingPractices.DataAccess.Contract;
    using MockingPractices.Domain;
    [TestClass]
    public class StudentRepositoryTest
    {
        [TestMethod]
        public void SaveShouldReturnSavedId()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                IStudentRepository studentRepository = new StudentRepository();
                Student student = new Student()
                {
                    Id = 0,
                    Name = "test name",
                    Email = "testemail@email.com",
                    Phone = "123456"
                };
                int id = studentRepository.Save(student);
                Assert.AreNotEqual(0, id);
            }
        }
    }
}

Now if we follow the below images, we can instruct the system to run the test method and execute the code inside of that method.

Walkthrough: Run the test method using Visual Studio Unit Testing Framework

  1. Move your cursor to the icon given in the below image.
  2. Click on that and press Run.
  3. A window will appear which indicates the status of the running test.
  4. If the test runs successfully, the following image should be appeared.

If you strictly follow my above instructions, you should now see the green sign as given below. Thus we can test our database code using unit testing without the help of any kinds of User Interface.

But there are some problems in the above work.

  1. We should not retain our test data into the database and
  2. We should not create the helping objects by us. Below is the way how we can solve those problems.

Main rule is we must revert the database insert operation after the test method. We can use TransactionScope class for that.

Secondly, we should use a framework to create those helping stubs. We will use NBuilder to build the objects for us. Installation of NBuilder can be done using Nuget.

You should see the installed packages in your project by going to the below image.

So, after coding to solve these problems, our code should look like this.

namespace MockingPractices.DataAccess.Test
{
    using System.Transactions;
    using FizzWare.NBuilder;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using MockingPractices.DataAccess.Contract;
    using MockingPractices.Domain;

    [TestClass]
    public class StudentRepositoryTest
    {
        [TestMethod]
        public void SaveShouldReturnSavedId()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                IStudentRepository studentRepository = new StudentRepository();
                Student student = Builder<Student>.CreateNew().With(s => s.Id = 0).Build();
                int id = studentRepository.Save(student);
                Assert.AreNotEqual(0, id);
            }
        }
    }
}

Run as many as you like the test just pressing the Run command. You will never need to open the user interface again and again and input the values and calculate the expected values by yourself. This is the true beauty of unit testing. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Foyzul Karim
Software Developer Secure Link Services Ltd.
Bangladesh Bangladesh
I am Software Engineer currently working in Secure Link Services Ltd. (http://selise.ch) and I also take classes on various topics of .NET Technologies at BASIS .NET Training Program (http://www.basis.org.bd/index.php/training), which is the best training program in Bangladesh.
Follow on   Twitter   Google+

Comments and Discussions

 
GeneralMy vote of 3 Pinmembermr_squall16-Dec-14 23:55 
GeneralMy vote of 5 PinmemberUnque12-Nov-12 15:49 
QuestionConnection String PinmemberFabio Galante Mans8-Nov-12 3:26 
AnswerRe: Connection String PinmemberFoyzul Karim8-Nov-12 5:19 
GeneralRe: Connection String PinmemberFabio Galante Mans8-Nov-12 6:32 
GeneralRe: Connection String PinmemberFoyzul Karim8-Nov-12 7:03 
GeneralMy vote of 2 PinmemberJohn Brett8-Nov-12 1:46 
GeneralRe: My vote of 2 PinmemberFoyzul Karim8-Nov-12 2:25 
GeneralRe: My vote of 2 PinmemberJohn Brett8-Nov-12 2:35 
GeneralRe: My vote of 2 PinmemberFoyzul Karim12-Nov-12 18:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141220.1 | Last Updated 13 Nov 2012
Article Copyright 2012 by Foyzul Karim
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid