Unit Testing – Dependencies

Summary

I’ve written about unit testing quite extensively, but this time I want to show a method to break dependency using some code that I blogged about earlier.  The code I’m talking about is used to detect if a method or class is being executed under a unit test.  In my example I’m going to pretend I’m designing a game (because I am) and show how to test the die roll.

To get started, I’ll describe what I’m trying to design.  Over a year ago, I blogged about a game I named Battle Field One.  This game is based on an electronic version of a physical board game using army tokens and a hex board.  When one unit attacks another unit, the result of the attack is determined by die roll.  In this unit test setup, I’m going to show how you can fake your die roller for unit testing purposes.


Getting Started

Why would we want to fake out the die roll?  If we’re unit testing, we want to control what the outcome is so we can test each outcome.  For instance, we can test what the battle outcome will be depending on each die roll.  If we don’t fake the die roll, then the random number generator will generate a number that we don’t know in the unit test and the test would be difficult to perform.

Next is the problem of multiple rolls.  We don’t just want to set one number, but we might want to stack the dice with numbers for the next N rolls of the dice.  So I’m gong to design a unit test helper to do this for us.


The Solution Setup

For my solution, I created four projects: A console, the game class, the unit test helper class and the unit tests class.  I’ll start with the game project, containing the GameClass.  In this project is just one class file that is called the DieRoller:

public static class DieRoller
{
    private static Random RandomNumberGenerator = new 

       Random(DateTime.Now.Millisecond);

    public static int DieRoll()
    {
        if (UnitTestHelpers.IsInUnitTest)
        {
            return UnitTestHelpers.SetDieRoll;
        }
        else
        {
            return RandomNumberGenerator.Next() % 6;
        }
    }
}

The DieRoll() method contains a call to the unit test helper class that has a SetDieRoll getter.  The UnitTestHelper class looks like this:

public class UnitTestHelpers
{
    public static bool IsInUnitTest
    {
        get
        {
            string assemblyName = 

            “Microsoft.VisualStudio.QualityTools.UnitTestFramework“;
            return AppDomain.CurrentDomain.GetAssemblies().Any(a => 

               a.FullName.StartsWith(assemblyName));
        }
    }
    private static int _NextDieRoll = 0;
    private static List<int> _SetDieRoll = new List<int>();
    public static int SetDieRoll
    {
        get
        {
            int nextDieRoll = _SetDieRoll[_NextDieRoll];
            _NextDieRoll++;
            if (_NextDieRoll >= _SetDieRoll.Count)
            {
                _NextDieRoll = 0;
            }

            return nextDieRoll;
        }
        set
        {
            _SetDieRoll.Add(value);
        }
    }
}

The “IsInUnitTest” will detect if the starting project is a unit test project (because it contains the “UnitTestFramework” dll).  The SetDieRoll getter, setter method is used to set one or more die rolls ahead of it’s use.  The getter will grab the next roll in the list and then wrap when the list has been exhausted.


Writing a Unit Test

[TestMethod]
public void TestDieRoll()
{
    UnitTestHelpers.SetDieRoll = 5;
    UnitTestHelpers.SetDieRoll = 2;
    UnitTestHelpers.SetDieRoll = 7;

    int result = DieRoller.DieRoll();
    Assert.AreEqual(5, result);

    result = DieRoller.DieRoll();
    Assert.AreEqual(2, result);

    result = DieRoller.DieRoll();
    Assert.AreEqual(7, result);
}

First, we put three numbers in our die.  Then we call the DieRoller three times and verify that the numbers that are read are the numbers that we stuffed.  


The Console Application

Next, we need to verify that the unit test part is not interfering with the normal “random” operation of the die.  So I wrote this dumb and dirty program to manually read a few die rolls:

class Program
{
    static void Main(string[] args)
    {
        int result = DieRoller.DieRoll();
        Console.WriteLine(result);
        Console.ReadKey();
    }
}


You should get a number between 1 and 6 each time you run the console application.  If you run the program more than once, you should get a different number each time.  What you should not get is a 5 followed by a 2 followed by a 7 (it could randomly happen, but probably not).  If you run the console and it always produce 5, then there is a problem.  You’ll need to investigate the IsInUnitTest method.


Download the Sample Solution

You can download my sample application by clicking here.

Update

There is a possible issue with running multiple unit tests with the static SetDieRoll method.  When one unit tests sets up the rolls, then another test inserts new data, the previous test data is still stored.  To fix this issue you should provide a DieClear() method, like this:


public class UnitTestHelpers
{

    public static void ClearDieRoll()
    {
        _SetDieRoll.Clear();
        _NextDieRoll = 0;
    }

}

Then add an initialize method to your unit tests:

[TestInitialize]
public void Initialize()
{
    UnitTestHelpers.ClearDieRoll();
}


This will clear any die roll information between multiple tests.

 

Creating a Windows Service Application

Summary

In this post, I’m going to show you the easiest way to get a service application up and running.  Windows Services can be used to perform background tasks while your computer or server continues to perform normal tasks.  Services can also run while a computer is logged out.


Getting Started

The first thing I do when I design a service application is separate the service part from the core code.  I also provide a method of testing my code while not in a service, so I can get feedback on a console screen and put breakpoints in the code instead of trying to read log files and reverse-engineer what is wrong with my program.

So step 1 is to setup a solution with three projects in it.  The first project is the core project itself.  This will be a C# library project and will all of the code that my program will use for it’s functions.  The second project will be a console application.  This application will do nothing more than call the entry program of the core project.  This console application will be used to troubleshoot issues.  The last project will be the service application.  This project will contain the service code plus an installer.  The service application does no more than the console application, call the entry program of the core project.  (see project selector below):



Don’t forget to set your console application as the default startup application (Right-click, select “Set as StartUp Project”).


Setting up the Installer


Technically, you don’t need an installer for your service, you can just manually install your program from powershell.  However, it is much easier to create an installer and then create a powershell script to check if the service is installed, and run your installer if it is not.  To add an installer, open your service project and double-click on the file named “Service1.cs” (assuming you left it the default file name).  You’ll be on a blank designer window.  Right-click on the designer window background and you’ll see this menu:


You should see something like this:



Select “Add Installer” and another file will appear in your project.  The default name is “ProjectInstaller.cs”.  Now expand the file by clicking on the triangle next to the “ProjectInstaller.cs” file and double-click on the file named “ProjectInstaller.Designer.cs”.  Open the region named “Component Designer Generated Code” where we can add a few lines of code.  The following snap shot highlights the added lines of code:



Connecting the Console and Service Applications to Core

Inside your console application, right-click on “References” and add the solution core.  Inside your services application, do the same, right-click on “References” and add the solution core.  Now you have to add the proper “using” statement at the top of your console application “Program.cs” file and add the “using” statement to your service application (called the “Service1.cs” file, right-click on Service1.cs and select “View Code”) so your console and service applications can reference the core project.


Writing Your Core Application

Now we need to create a starting program cs file, I’ll call it “StartingClass.cs” which is the beginning of the program.  Here’s the program shell:

public class StartingClass
{
    private volatile bool _stopAgent;
    private static StartingClass _instance;

    public static StartingClass Instance
    {
        get { return _instance ?? (_instance = new StartingClass()); }
    }

    private StartingClass()
    {
        _stopAgent = false;
    }

    public bool Stopped { get; private set; }

    public void Start()
    {
        ThreadPool.QueueUserWorkItem(action =>
        {
            while (!_stopAgent)
            {
                // do something here
                using (StreamWriter writer = new StreamWriter(“c:\TestService.txt“, true))
                {
                  writer.WriteLine(“Service is running ” + DateTime.Now.ToString(“H:mm:ss“));
                }

                if (!_stopAgent)
                {
                    Thread.Sleep(5 * 1000); // wait 5 seconds
                }
            }

            Stopped = true;

        }, TaskCreationOptions.LongRunning);
    }

    public void Stop()
    {
        _stopAgent = true;
    }
}

You’ll have to add “usings” for these three dlls:

using System.Threading.Tasks;
using System.Threading;
using System.IO;


The first thing that this object does is provide a static instance.  This is just for convenience.  The constructor initializes the _stopAgent value to false.  This will be set by the calling program (either the console when the user hits a key or the service when someone clicks the service stop button).  The “Start()” method is the guts of this program.  This is wrapped in a threadpool so that your service doesn’t get hung when you start it up.  The service will kick off your program and then continue on it’s way (which we will program to remain idle).  Inside the threadpool is your program’s main loop.  You can process something inside this loop (calling other classes if necessary) until the service is stopped.  For this little sample, I’m just going to keep appending the current time to a text file on the C: drive every 5 seconds.


Your Console Application

Let’s get the console application together so we can test the code before moving on to the actual service application.  The code for your console application should pretty much always look like this:

static void Main(string[] args)
{
    StartingClass.Instance.Start();

    Console.WriteLine(“Press any key to gracefully stop the processing…“);
    Console.ReadKey();
    StartingClass.Instance.Stop();

    Console.WriteLine(“Processing stopped. Press any key to exit…“);
    Console.ReadKey();
}

 Now run your console application and see what happens.  First, you’ll see the console screen appear and wait for input to stop.  If you navigate to your C: drive and find the “TestService.txt” file, you can open it and see the time inside.  If you close it and re-open it after 5 seconds have elapsed, you’ll another time appended to the file.  This will continue until you stop your console application.


Your Service Application

Now go to your service application.  Find “Service1.cs”, right-click on it and “View Code”.  You will see an OnStart() and an OnStop() method inside the main class.  You will call your start() method from the OnStart() and call your stop method inside your OnStop() method.  Yes, it’s that easy.


The Powershell Installation Script

Here’s the script to install or re-install your service (name it powershellscript.ps1):

#If service is installed, stop it; else install it.
$serviceFullPath = “path_to_service_exe_fileBlogServiceSample.exe”

Write-Host “Installing service…” -foregroundcolor cyan

Invoke-Command -ScriptBlock { C:WINDOWSMicrosoft.NETFrameworkv4.0.30319InstallUtil.exe /install “$serviceFullPath”}
}

Write-Host “Starting MyService service…” -foregroundcolor cyan
Start-Service MyService

Write-Host “Deployment Complete!” -foregroundcolor Green

You’ll have to navigate to the path of our service executable and paste it into the script above (you can download the file and change the path name).  Then you’ll have to start up powershell.  Run powershell as an administrator:


If you’ve never run powershell before, you’ll probably have to run a command to make it override the system script safety.  Otherwise you’ll get a message indicating that your script cannot be loaded because the execution of scripts is disabled on this system…etc. etc.

So Run the following command:

set-executionpolicy remotesigned

Then run your script:

./powershellscript.ps1

and you should see something like this:



Obviously, the path to your source will be different from mine, but the end of your script should produce the same “Deployment Complete!” message.


Verify Your Service is Running

Go to your control panel -> System and Security -> Administrative Tools  and double-click on “Services”.  You should be able to scroll down and find a service called “MyServiceDisplay”.  Now you know where that is set in your program (inside the ProjectInstaller.cs file).  If you double-click on that line, you’ll see that your service is already started and the service name is “MyService”.  Now go to your C: drive and you should see a text file named “TestService.txt”.  Open this file and you’ll see new time entries.  Close and open this file and additional time entries should appear at 5 second intervals.  Cool eh?


Stopping Your Service

Go back to the Services control panel and double-click on “MyServiceDisplay” and you’ll see the properties window:


Click the “Stop” button and your service should stop.  Check your text file and make sure no more times are appearing.  You have verified that your service works.

If you change your program, you will need to manually stop your service, re-build your application, then manually restart your service.  If you are creating a deployment script you’ll want to make your script stop the service (if it is already installed) copy the exe file over the existing one and then restart the service.  If you want to be safe and provide a roll-back capability, you’ll need to stop your service, copy your new exe into a new directory every time, then change the path of the service to point to the new service and start it back up. I’ll leave that for another blog post.


Deleting a Service

Open a command window (Start menu, type in “CMD”), then type in:

sc delete MyService

You should see a confirmation message:

[SC] DeleteService SUCCESS



Source Code:


BlogServiceSample.zip
powershellscript.zip




 

How to detect if your code was called from a unit test

I’ve done a few unit test blog posts, but this time I’m going to demonstrate how to detect if a method is running under a unit test.  This flag can be used to break dependencies in an object or run a test database instance instead of the production instance.  

The first article I stumbled across was this stack overflow article on just such a problem:

determine-if-code-is-running-as-part-of-a-unit-test

Answer #22 had my solution, using reflection to determine if one of the included DLL’s was the UnitTestFramework.


public static class UnitTestDetector
{
    public static bool IsInUnitTest()
    {
        string assemblyName = 
         “Microsoft.VisualStudio.QualityTools.UnitTestFramework“;
        return AppDomain.CurrentDomain.GetAssemblies().Any(a => 
                   a.FullName.StartsWith(assemblyName));
    }
}


So what’s the point?  The purpose of this class/method is to embed this into your context code and force your ORM to use a test database when you are running unit tests, but run your production database when the calling assembly is not a unit test assembly.  By using this code to switch your database at the context level, you no longer have to worry about breaking dependencies of your objects that will be under unit test.

Another advantage is that this can be used in multiple ORM’s (such as EF, NHibernate, etc.).  It can even be used in direct queries if you have a SqlConnection wrapper that feeds the connection string in one place.

In a future post, I’ll demonstrate how to use this class/method in Entity Framework and show how to connect EF to SQLLocalDB for unit testing purposes.

 

Removing the NuGet Package Manager Files

Summary

The NuGet package manager is handy for finding DLLs and supporting modules when you want to get something up and running fast.  I like the search capability and the fact that the package knows what to install to make it work.  However, I don’t like the fact that the package manager downloads every .Net version of the package plus every conceivable support file.  I understand why it operates the way it operates, and I’ve seen the NuGet manager update packages when I change the .Net version of projects, etc. etc.  In this post, I’m going to show how to unload the NuGet baggage and strip your application to what is needed.  This will reduce the size of your installation and/or deployment package.


The NuGet Package Manager

You can add DLLs to your project by going to the Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution (or you can use the console).  Then select a package and hit the “Install” button.  Some projects have packages already installed.  One such project is the MVC4 project.  If you open Visual Studio (I’m currently using VS 2012) and select “New Project”, then inside the “Web” projects, select “ASP.Net MVC4 Web Application”, then select the “Empty” application.  Once the project is completed, you’ll see a file in your project called “packages.config”.  Open that file (it’s an XML file, just double-click on it).  Listed in this file are all the DLLs in the NuGet package.  This will be your key to untangling the needed components.

In my sample, I have this in my packages.config file:

<?xml version=”1.0encoding=”utf-8“?>
<packages>
  <package id=”Microsoft.AspNet.Mvcversion=”4.0.20710.0targetFramework=”net45” />
  <package id=”Microsoft.AspNet.Mvc.FixedDisplayModesversion=”1.0.0targetFramework=”net45” />
  <package id=”Microsoft.AspNet.Razorversion=”2.0.20715.0targetFramework=”net45” />
  <package id=”Microsoft.AspNet.WebApiversion=”4.0.20710.0targetFramework=”net45” />
  <package id=”Microsoft.AspNet.WebApi.Clientversion=”4.0.20710.0targetFramework=”net45” />
  <package id=”Microsoft.AspNet.WebApi.Coreversion=”4.0.20710.0targetFramework=”net45” />
  <package id=”Microsoft.AspNet.WebApi.WebHostversion=”4.0.20710.0targetFramework=”net45” />
  <package id=”Microsoft.AspNet.WebPagesversion=”2.0.20710.0targetFramework=”net45” />
  <package id=”Microsoft.Net.Httpversion=”2.0.20710.0targetFramework=”net45” />
  <package id=”Microsoft.Web.Infrastructureversion=”1.0.0.0targetFramework=”net45” />
  <package id=”Newtonsoft.Jsonversion=”4.5.11targetFramework=”net45” />
</packages>

First create a directory in your project, or you can create a directory in your solution to contain the DLLs that you’ll be using.  I usually name it “3rdPartyDLLs”.  If you have a lot of projects that use the same DLLs, you can create a shared directory.  I prefer to keep the DLLs with the project, so I know the versions match the project when it was designed.  Next, you’ll need to open the “References” directory of your project.  Look at the first DLL that is listed in the xml file and match the name with the DLL listed in the References.  If the DLL is in the References, then navigate to the solution folder and find the “packages” folder.  Open that folder, drill down to find the matching DLL.  If there are two or more .Net folders, then check the version in the XML file (most of the above are .Net 4, but some are 2).  Drill into the .Net folder and copy the dll and xml (if it exists) files into your “3rdPartyDLLs” folder (just drag the files into your project folder of visual studio, a copy will be made).

Next, delete the reference in your “References” folder.  Then “add reference” by right-clicking on the “References” folder and selecting “add reference”.  Use the browse button to navigate to your project’s “3rdPartyDLLs” folder and select the DLL file that you just removed from the “References” folder.

Last, delete the entry from the packages.config file.  Rebuild your project to make sure it still builds.  If it does not build, you might need to make the reference DLL copy local (click on the DLL in the “References” folder and you’ll see in the properties window a “Copy Local” flag.  Change that to “Yes”).

Now repeat this process until you have an empty packages.config file.


Final Cleanup

The final cleanup involves deleting the packages.config file in your project.  Then delete the entire “packages” folder in your solution folder (you may have difficulty deleting the whole thing at once because Windows thinks that those files are opened someplace.  I usually drill down into sub directories and delete the stubborn dlls first.  Then back-out and delete the whole thing).  

Now make sure you rebuild your project and fix any errors.

You can verify that you removed all NuGet package components when your packages.config file doesn’t re-appear and you can click on each DLL in your “References” folder and make sure the Path to each file doesn’t point to a package folder.

 

Fluent NHibernate Custom SQL Types

When mapping data types from SQL server into Fluent NHibernate, the generic mappings work just fine (as long as the data in the field fits the type declared).  In other words, a char(50), a text or a varchar(max) field in SQL server will fit in a string type without an issue.  There is one problem that can occur if you’re attempting to unit (i.e. integration) test a database and you use the SchemaExport.Create() method to generate your tables.  In this instance you’re attempting to map a string into something that the mapper will guess at.  To get it in the type that matches your database, you can declare the SQL server field type in your mappings.

Here’s an example table for storing information about a store (I’ve used this table in previous blog posts):

public class StoreMap : ClassMap<Store>
{
    public StoreMap()
    {
        Table(“sampledata..Store“);
        Id(u => u.id);
        Map(u => u.Name).CustomSqlType(“char(50)“).Length(50).Nullable();
        Map(u => u.Address).CustomSqlType(“char(50)“).Length(50).Nullable();
        Map(u => u.City).CustomSqlType(“char(50)“).Length(50).Nullable();
        Map(u => u.State).CustomSqlType(“char(50)“).Length(50).Nullable();
        Map(u => u.Zip).CustomSqlType(“char(10)“).Length(10).Nullable();
    }
}

You can use any of the mapping types listed here.  I have also successfully used many of the data types that SQL uses such as “money”, “text” and “varchar”.