Wednesday, October 30, 2013

Test Driven Development - Part V - Dealing External Dependency with Mock

As I mentioned in the previous session, Stubs are used to test the logic of the class under test  without considering how the dependant objects interact with thc class under test. Some times we need to test how the class under test interacts with the dependant objects or we need to make sure that the class under test interacts correctly with the dependant objects. Mocks are being used in this scenario. So by using Mocks, we are testing wheather the class under test has interacted correctly with the dependant object by verifying the Mock object.


Consider a scenario like the FileUpload class is logging the errors  and whenever an exception happens to the logging, it will mail the exception to the given mail address. Here we are using two dependent classes. One is for logging the errors and one for mailing the exception. If you want to test whether the mails are sending correctly for the exceptions we have to check the mail service object. For that we have to use the  Mock. A stub can be applied for Log service object. The below code shows how to implement it.

1. LogService Interface

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 namespace ManualMock_TDD  
 {  
   public interface ILogService  
   {  
     void WriteLog(string logmessage);  
   }  
 }  

2. MailService Interface

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 namespace ManualMock_TDD  
 {  
   public interface IEmailService  
   {  
     void SendEmail(string To, string Subject, string Body);  
   }  
 }  

3. The FileUpload Class

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.IO;  
 using ManualMock_TDD;  
 namespace Simple_TDD  
 {  
   public class FileUpload  
   {  
     private ILogService _LogService;  
     private IEmailService _Email;  
     public ILogService LogService  
     {  
       get { return _LogService; }  
       set { _LogService = value; }  
     }  
     public IEmailService EmailService {  
       get {return _Email ;}  
       set {_Email=value ;}  
     }  
     public void ValidateFilename(string filename)   
     {  
       //return ValidateObj.IsValid(filename);  
       if (filename.Length < 8)  
       {  
         try  
         {  
           LogService.WriteLog("file name is too short");  
         }  
         catch (Exception ex)  
         {  
           EmailService.SendEmail("mail@me.com", "Error occured while writing log", ex.Message);   
         }  
       }  
     }  
   }  
 }  

4. The Unit Test Class

 using Simple_TDD;  
 using Microsoft.VisualStudio.TestTools.UnitTesting;  
 using System;  
 namespace ManualMock_TDD.Tests  
 {  
   [TestClass()]  
   public class FileUploadTest  
   {  
     [TestMethod]  
     public void ValidateFilename_EmptyFileName_WillSendEmail()  
     {  
       StubLogService logservice = new StubLogService();  
       logservice.ToThrow = new Exception("filename to short");  
       MockEmailService eMailService = new MockEmailService();  
       FileUpload Target = new FileUpload();  
       Target.LogService = logservice;  
       Target.EmailService = eMailService;  
       Target.ValidateFilename("abc.txt");  
       Assert.AreEqual("mail@me.com", eMailService.To);  
       Assert.AreEqual("Error occured while writing log", eMailService.Subject);  
       Assert.AreEqual("filename too short", eMailService.Body);  
     }  
   }  
   class StubLogService : ILogService  
   {  
     public Exception ToThrow;  
     public void WriteLog(string msg)  
     {  
       throw ToThrow;  
     }  
   }  
   class MockEmailService : IEmailService  
   {  
     public string To;  
     public string Subject;  
     public string Body;  
     public void SendEmail(string to,string subject,string body)  
     {  
       To = to;  
       Subject = subject;  
       Body = body;  
     }  
   }  
 }  


In the example, the FileUpload class is using two interface objects. One for log service and another for email service.  For unit testing we use stub for  Log Service and mock object for Email. We need mock object for email here because we are going to check the content of the mail sent by the FileUpload class. To generate the scenario, the StubLogService will throw an exception. Then the FileUpload class will  call the mail service and will send the exception to the address given. The assertions will be done on the mail object. The last three lines in the test method is verifying the mail object to ensure about the exception handled in the  FileUpload class

Monday, October 28, 2013

Test Driven Development - Part IV - Dealing with External Dependency using Stub

An external dependency is an object in your system that your code under test interacts with, and over which you have no control. (Common examples are filesystems, threads, memory, time, and so on.). Mocks and Stubs are used to deal with external dependency. Both are fake objects to represent external dependent objects.Before going deep into mock and stub, we have to know how to refactor our code to apply mocks and stubs. Refactoring is the act of changing the code’s design without breaking existing functionality.

Consider our file upload class we used in the previous session. Assume that we have a file stored in the filesystem which consist of the rules related to the validation. The file upload class will have to validate the file name against the rules in the file. In this case, there we have a Validate class which deals with the accessing the file and validating the file name.   This Validate class is the dependency class of File upload class.
In order to break the dependency, we have to add one more layer of indirection. It can be either an Abstract Class or an Interface. Both have its own advantages and disadvantages. Here I am using Interface as the layer of indirection. So we have to do the following
  1. Extract an interface to allow replacing underlying implementation.
  2. Receive an interface at the constructor level or as a property.
After refactoring our code to a loosely coupled architeture, we can easily inject mock or stub into the application for the purpose of testing

STUB


Stub is a fake object the class under test has depended on. Stubs are used to by pass an external dependency. If a class is having external dependency, the unit test will fail when the dependency fails even if the logic in the Class Under Test is correct. Stubs are used to overcome this kind of issues. The unit test will test the class under test and during the process the Class Under Test will call the Stub class  instead of  calling the real external dependent object which will return the expected result to the class under test. The assertion is done with the class under test.

Example

IValidate Interface
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 namespace ManualStub_TDD  
 {  
   public interface IValidate  
   {  
     bool IsValid(string Filname);  
   }  
 }  

FileUpload class

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.IO;  
 using ManualStub_TDD;  
 namespace Simple_TDD  
 {  
   public class FileUpload  
   {  
     private IValidate ValidateObj;  
     public IValidate ValidationObj {   
       get{return ValidateObj;}  
       set { ValidateObj = value; }  
     }  
     public bool ValidateFilename(string filename)   
     {  
       return ValidateObj.IsValid(filename);  
     }  
   }  
 }  

Unit Testing project
 using Simple_TDD;  
 using Microsoft.VisualStudio.TestTools.UnitTesting;  
 using System;  
 using ManualStub_TDD;  
 namespace ManualStub.Tests  
 {  
   [TestClass()]  
   public class FileUploadTest  
   {  
     [TestMethod]  
     public void ValidateFileName_FilenameShorterThan6Letters_ReturnsFalse()  
     {  
       ValidateStub Vstub = new ValidateStub();  
       Vstub.StubReturnValue = false;  
       FileUpload target = new FileUpload();  
       target.ValidationObj = Vstub;  
       bool actual = target.ValidateFilename("abc.txt");  
       Assert.AreEqual(false, actual, "Method Allows shorter filenames");  
     }  
   }  
 }  
  class ValidateStub : IValidate  
 {  
   public bool StubReturnValue;  
   public bool IsValid(string filename)  
   {  
     return StubReturnValue;  
   }  
 }  


Here there is an IValidate interface and it contain the IsValid method. The Validate class will implement the IValidate interface. The "ValidationObj" prpoerty in the FileUpload class  will hold instance of classes implementing Ivalidate interface.  The ValidateFilename method will use this property to validate the file name and will return the boolean result.

For the purpose of unit testing, an internal stub class is created which implements the Ivalidate interface. To control the output, one more property has been added to the class. The stub will be initialized  in the Test Method. And that stub will be passed to the Target as property. And the method will evaluate the class under test.

Wednesday, May 15, 2013

Test Driven Development - Part III - Microsoft Testing Tools

Microsoft has also developed their own testing tools. Since VS2005, It has been integrated with the IDE. One of the main advantage of using Microsoft testing tool is the debugging feature with it. But it is not a standalone application. So you need to open the project whenever you want to run the tests.

We can start by opening the same project we did in the previous example.
Add new project to the solution by selecting File => Add => New Project => Visual C# => Test => Unit Test Project.(In VS2010 we had an option to create unit test project by right clicking on the method and selecting 'Create Unit Tests...'  from the popup menu. In VS2012 that feature has been dropped.)

Enter the Name "TddwithNunit.Tests2" and press OK button
The Project will be added to the solution. The project will be referenced to "Microsoft.VisualStudio.QualityTools.UnitTestFramework " and the project will have the following code.

 using System;  
 using Microsoft.VisualStudio.TestTools.UnitTesting;  
 namespace TddwithNunit.Tests2  
 {  
   [TestClass]  
   public class UnitTest1  
   {  
     [TestMethod]  
     public void TestMethod1()  
     {  
     }  
   }  
 }  

Unlike Nunit, Microsoft uses [TestClass] and [TestMethod] attributes for Class and Methods respectively. Add reference to the TddwithNunit project. Rename the class file to "FileUploadTests" and modify the code as below.

 using System;  
 using Microsoft.VisualStudio.TestTools.UnitTesting;  
 namespace TddwithNunit.Tests2  
 {  
   [TestClass]  
   public class FileUploadTests  
   {  
     [TestMethod]  
     public void ValidateFileName_FilnameShorterthan6letters_ReturnsFalse()  
     {  
       //Assign  
       fileupload file = new fileupload();  
       //Act  
       var result = file.ValidateFileName("abc.txt");  
       //Assert  
       Assert.IsFalse(result, "Shorter Filenames are returning true");  
     }  
   }  
 }  


Now build the solution.

Select => Test =>Run =>All Tests . The result of the test will be displayed in Test Explorer inside the IDE as below.


The test has been failed. This logic has not been implemented into the ValidateFilename method. We have to refactor the code as below

 public class fileupload  
   {  
     public bool ValidateFileName(string filename)  
     {  
       bool returnvalue = false;  
       if (filename != string.Empty)  
       {  
         var filepart1 = filename.Split('.').First();  
         if (filepart1.Length >= 6)  
           returnvalue = true;  
       }  
       return returnvalue;  
     }  
   }  
 }  

And run the Test again from the Test Explorer => Run All


The test has been succeeded this time.

Wednesday, May 1, 2013

Test Driven Development - Part II - Working with NUnit


NUnit is a popular unit-testing framework for all .Net languages. It is xUnit based unit testing tool for Microsoft .NET. xUnit is a collection unit testing frameworks which  provides an automated solution with no need to write the same tests many times, and no need to remember what should be the result of each test

xUint is originally develped by Kent Beck. , the brain behind test driven development.

NUnit is an open source testing tool. It can be downloaded from www.NUnit.org  It is a stand alone application. So we can run the test any time without opening the Visual Studio Project.

Here is an simple example of doing a TDD in Visual Studio with NUnit

Open Visual Studio 2010/2012
Select File => New Project => Visual C# => Console Application
Enter Project Name 'TDDWithNunit' and press OK button
Add a class with name 'fileupload' to the project
Add the following code to the class


 public class fileupload  
   {  
     public bool ValidateFileName(string filename)  
     {  
       throw new NotImplementedException();  
     }  
   }  


Now we are about to start the coding for 'ValidateFileName'. But in test driven development, we have to write the unit test before writing actual development code. The above code is just enough to compile the project.

Add new project to the solution by selecting File => Add => New Project => Visual C# => Class Library
Enter the Project Name ' TDDWithNunit.Tests'
Rename the Class1.cs to "fileuploadTests.cs"

For each class we have to create corresponding unit testing class. For the readability it would be better to give the test class name as "<Class Under Test Name>Tests"

We need to add reference to the project under test to the unit testing project.  Right click References  and select Solution => Project => TddwithNUnit.

Add NUnit framework reference to the project from Assemblies => Extensions =>nunit.framework
Add the following code to the Test class.
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using NUnit.Framework;  
 namespace TddwithNunit.Tests  
 {  
   [TestFixture]  
   public class fileuploadTests  
   {  
     [Test]  
     public void ValidateFileName_EmptyFilname_ReturnsFalse()  
     {  
       //Assign  
       fileupload file = new fileupload();  
       //Act  
       var result =file.ValidateFileName("");  
       //Assert  
       Assert.IsFalse(result, "Filename allows empty string");  
     }  
   }  
 }  

In the above code, [TestFixture] attribute has been added to the class and [Test] attribute has added to the testing method as well. This two attributes are required for the Nunit framework to detect the test class and methods. Naming of methods also need some attention. It should be "Public" and "void". It will be better to name the testing method in manner like __. It will help to find the issue easily even the method contains more number of methods. Now build the application. Load Nunit from the Start Menu Select File => Open Project =>\bin\Debug\ TddwithNunit.Test.dll





It will display the test class and method as in the above image Click the Run button


The method will fail because the method is not implemented. It will be indicated by the red line. Now modify the ValidateFileName method as below

  public bool ValidateFileName(string filename)  
     {  
       //throw new NotImplementedException();  
       if (filename != string.Empty)  
       {  
         return true;  
       }  
       else { return false; }  
     }  

Build the Application Run the NUnit Application. It will load the project automatically
Click the Run button

The test passed this time with the green signal. We can refactor the code now.

Tuesday, April 23, 2013

Test Driven Development - Part I - Introduction

What is Test Driven Development? 

Microsoft defines Test Driven Development as "Test-driven development (TDD) is an advanced technique of using automated unit tests to drive the design of software and force decoupling of dependencies. The result of using this practice is a comprehensive suite of unit tests that can be run at any time to provide feedback that the software is still working. This technique is heavily emphasized by those using Agile development methodologies".

So from the definition  it is clear that TDD is based on automated unit tests. To continue with TDD we have to know Unit Testing. Before going deep into the Unit Testing , we will look into the concept of TDD little more...

The principle of Test Driven Development is Red => Green => Refactor.




In the above figure, the development or the coding is start by writing the unit tests. It fails for the first time as there is no code to compile. It fails for the second time also because of lack of logic specified in the unit test. Whenever a test fails, the unit testing framework will indicate it by the Red signal. And when the test passes it will be indicated by the Green signal. That is why Red => Green => Refactor becomes the mantra of Test driven development.

What is Unit Testing?

A unit test is an automated piece of code that invokes the method or class being tested and then checks some assumptions about the logical behavior of that method or class. A unit test is almost always written using a unit-testing framework. It can be written easily and runs quickly. It’s fully automated, trustworthy, readable, and maintainable.

A good unit test should have the following properties

  • It should be easy to implement.
  • It should be automated and repeatable.
  • Once it’s written, it should remain for future use.
  • Anyone should be able to run it.
  • It should run at the push of a button.
  • It should run quickly.