Subscribe RSS 2.0 cshandler feeds

Sunday, 6 April 2014

VS 2012 Fakes - Testing the Untestable

I have always been the great fan of TDD approach of coding. But recently, I've ran into case with a situation when the code was not Testable. Before we go ahead into further details I would like to put a disclaimer.

This is not an en talk but I'm expecting you are:
1. Familiar with Unit testing
2. Mocking and faking the real dependencies
3. Writing testable code

 

If you agree with above Agreement then I'm sure you'll enjoy this reading.
We Write testable code to make the external dependencies injectable via dependcy injection and faking/mocking them while unit testing. But what if:
1.  you have too many dependencies and you can't take put like 6-7 things to inject via constructor. Ofcourse it will look ugly in the code.
2. you have some dependecies that you can't fake. So you wrap the dependency in one of your own interface with implementing the real deal. But this is too much of writing code for getting rid of that thing.
3. You have to test the Legacy code that is Either "Restricted" for refactoring or "Refactoring" Cost you a lot as stakeholders don't want you put that much efforts in it.


As mentioned above, You might be having enough reasons to stuck and thinking what should I DO NOW?????

 

 

 


Let's take you a hope of life and let's discuss about the new Visual Studio 2012 Fakes feature which available in Premium and above versions only. That's enough of explanation I won't deep dive into how it comes into the picture blah blah.. but this would be your plan B for survival. So let's take a sample of code and finding the problem on the way:

I have this simple class that reads the configuration appsetting for reading the connectionString from Appsetting.

/// <summary>
/// Configuration class that fetches the connection string.
/// </summary>
public class UntestableClass
{
private readonly string connectionString;

private readonly string connectionStringKey = "LocalConnectionString";

/// <summary>
/// Initializes a new instance of the <see cref="UntestableClass"/> class.
/// </summary>
public UntestableClass()
{
connectionString = ConfigurationManager.AppSettings[connectionStringKey];
}

public string GetConnectionString()
{
if (string.IsNullOrWhiteSpace(connectionString))
{
throw new ArgumentNullException("The connection-string section was not found in the configuration.");
}

return this.connectionString;
}
}

This class can be tested but not without using the App.Config file. You can handle this situation by writing custom Appsetting reader that uses the ConfigurationManager or can be injected via dependency injection. But I don't want to refactor my code.

So let's go and write a test class for this. I'm using Nunit framework for writing the tests here.

 

[TestFixture]
public class UntestableClassTests
{
[Test]
public void GetConfiguration_InvalidConfigurationFound_ThrowsException()
{
UntestableClass objUnderTest = new UntestableClass(); // Here this will gonna use the actual configuration manager

var result = objUnderTest.GetConnectionString();

Assert.IsNotEmpty(result);
}
}

This is what our test would look like but I don't want to use the Real configuration manager class so let's deal with it. If you look at your references in the Test project. Right click on the referenced assembly and choose "Add Fakes Assembly".


image
image
This will add few thing in the project. One is Fakes Folder and an xml file containing the information about the faked assembly and a new reference for the faked Assembly of target.

Note: You don't have to checkin the generated assembly because they can be generated during build easily and with no extra costs.

Now we have the all the classes faked in the assembly. So I can use a faked one i.e. ConfiguationManager. This what our new tests would look like:
SNAGHTML5f0cc2a6
you might have notices few thing in this new test here. The actual class is now replaced with Shim class. You can read about the Shims and Stubs in details on MSDN.
Now if let's try to run this code:
image
So you see the test have failed. And we've got the generous message from the VS test runner. Let's modify the code as per the VS wanted.


[TestFixture]
public class UntestableClassTests
{
[Test]
public void GetConfiguration_InvalidConfigurationFound_ThrowsException()
{
using (ShimsContext.Create())
{
var appsettings = new NameValueCollection();
appsettings.Add("LocalConnectionString", "/*** Some connection string ***/");

// Changing the default behavior appsetting and put our custom behavior
ShimConfigurationManager.AppSettingsGet = () => appsettings;

// Here this will now use the faked configuration manager
UntestableClass objUnderTest = new UntestableClass();

var result = objUnderTest.GetConnectionString();

Assert.IsNotEmpty(result);
}
}
}

Running the code will result in -
image
Note: Other test runner might throw another exception e.g. The Test runner available via Resharper will fail with below message.
Microsoft.QualityTools.Testing.Fakes.UnitTestIsolation.UnitTestIsolationException : UnitTestIsolation instrumentation failed to initialize. Please restart Visual Studio and rerun this test
Reason: This happened because the executing assembly needs to be modified and needs to be instrumented for placing your custom behavior. So any test runner who have the permission to instrument the assembly can be used. I used VS test runner in this demo.


Hope you enjoyed this. I'll be discussing the Shims and Stubs in details in next post. Keep tune in.





Image courtesy: (themetapicture.com, wackybuttons.com)

Wednesday, 22 January 2014

Learn basic unit testing with VS2012 and Nunit

This post is a guide for basics of Unit testing. Through this article we’ll go step by step setting up the Environment and few basic test scenarios. To start with hands on you need following installed on you machine.

Download

image

If you already have Visual studio installed then you need to install the Nuget Extension Manager extension of Visual studio.

Now you’re ready to install the libraries which are available on Official Nuget server. For this exercise we’ll be using Nunit testing framework. The nuget manager will Install the Nunit Framework and Nunit test adapter from the Visual studio itself. So like the old days you don’t have to go to web and download the Nunit package and then adding to the visual studio. Nuget is the new RAD tool that won’t let you go off the Visual studio Interface.

So now we have the tools so let’s get started:

1. Launch the visual studio and create new Class Library project.

image

2. Now let’s write some logical methods for e.g. just simple numeric and string operations.

public class LogicalClass
{
    /// <summary>
    /// A sample divide operation
    /// </summary>
    /// <param name="a">Any positive integer</param>
    /// <param name="b">A non zero value</param>
    /// <returns>result of divide operation as decimal</returns>
    public decimal Divide(int a, int b)
    {
        if (b == 0)
        {
          throw new DivideByZeroException("Lets ensure.");   
        }
 
        return (a / b);
    }
 
    /// <summary>
    /// The concat two names.
    /// </summary>
    /// <param name="name1"> The name 1. </param>
    /// <param name="name2"> The name 2. </param>
    /// <returns> The <see cref="string"/>. </returns>
    public string ConcatTwoNames(string name1, string name2)
    {
        return string.Format("{0}.{1}", name1, name2);
    }
}

Now since this is a class library and to ensure that my logic is working fine without debugging, We’ll write some more code which will unit test the methods.


3. Let’s proceed with creating a new project as Class library called DemoLibrary.UnitTests


image


Now before we start writing the unit tests for the LogicalClass we would need the Testing framework. You can also use the same Microsoft.Tests but I’m quite fond of Nunit. But there’s no such difference which framework you would use, If you’re interesting in comparing these two frameworks capabilities then you can visit the comparison list here.


4. To install the Nunit framework right click on the Unit test project and select Manage Nuget package. This will open the window showing the online Packages available. Search for Nunit and you’ll see the result shown as in below image.


image


Install the Nunit and Nunit Test Adapter for VS2012 & 2013. Why do we need test adapter? To find and run the Unit tests the Nunit test adapter will do the work for you. You can also install the extension of Nunit Test Adapter. Go to Extension Manager –> Search “Nunit Test Adapter” and Install.  Though Visual studio can also find tests and you can run them by going to menu Test –> Windows –> Test Explorer.


image


Now setup is finished so start writing the Unit tests. Let’s add a class named LogicalClassTests this is a naming convention you must follow as this will make your tests easily identifiable just by name of the Test class.


Now the test class will have following things you need to learn to make a test perfect looking and runnable.


image


TestFixture Class Attribute – This attribute is to mark a class as test suite which will contain tests.


Test Method Attribute – This attribute is to mark a method as a Unit test. Only methods with this attribute would be runnable by test runner.


Setup – To initialize the object to be tested and initial values required for the test. In upcoming article we’ll learn how to Fake/Mock the dependencies like Database, FileSystem, Or any other external system while writing tests. This will be the part of setup.


Act – Act is actually when you call the method that you’re going to test. So you provide the test values to the method and receive an output which will be tested against the expected result.


Assert – Assert is the statement which will check the expected values by the result.


Similarly, you’ll write the tests for all the positive scenarios of a method. To download the demo exercise files you can download them from here.


Source Code: https://db.tt/NwTlSIvu

Monday, 6 January 2014

Unit testing async marked methods using mock library

Have you ever tried unit testing a method marked with async? There’s a known problem of unit testing the Async marked methods. When Nunit tried to run the test with mocked Async methods it goes in Infinite wait. There are many discussion on the internet for the same giving you the solutions and work around. This post will provide you with another solution.

Let’s start and setup a test project to reproduce the problem. So first we need library that contains the methods marked with Async keyword.

First we need the marker interface:

IHttpDownloader.cs

public interface IHttpDownloader
{
    Task<string> DownloadContentAsync(Uri httpUri);
}

Implementation:


HttpDownloader.cs



public class HttpDownloader : IHttpDownloader
{
    public async Task<string> DownloadContentAsync(Uri httpUri)
    {
        RawHttpDownloader downloader = new RawHttpDownloader();
 
       return await downloader.DownloadAsync(httpUri);
    }
}

Helper class:


RawHttpDownloader.cs



public class RawHttpDownloader
{
    public async Task<string> DownloadAsync(Uri httpUri)
    {
        return string.Format("Dummy downloaded string from {0}", httpUri.AbsolutePath);
    }
}


Now lets write a unit test to test this method for a positive scenario. Here I have used the Nunit to write the tests:



[TestFixture]
public class HttpDownloaderTest
{
    [Test]
    public void DownloadContentAsync_ValidHttpAddress_ReturnsData()
    {
        var repository = new MockRepository();
        var httpUri = new Uri("http://www.google.com/about");
 
        var downloaderStub = repository.Stub<IHttpDownloader>();
 
        // setup
        var task = new Task<String>(
            () => { return "test string"; });
 
        downloaderStub.Expect(s => s.DownloadContentAsync(httpUri)).Return(task);
 
        // act
        repository.ReplayAll();
 
        var restult = downloaderStub.DownloadContentAsync(httpUri);
 
       Assert.IsNotNull(restult.Result);
 
        repository.VerifyAll();
    }
}

If you try to run this test It will go in Infinite state:


image


Problem caused by the Nunit framework as it doesn’t support the methods marked with Async keyword for tests. So it kept on waiting for the asynchronous method and it actually never invokes the Task returned into start state.


Solution:


Since the Nunit doesn’t actually invokes the underlying task to start state so you what you just have to do is Start the task manually.


image


 


Download the complete sample from here.

Thursday, 5 December 2013

Using generic List as key in Dictionaries

Dictionaries in CSharp are datastructure which represents hash maps. You can store key value based data easily also it prevents to insert duplicate keys. But sometime it comes as requirement where you have a list of items which you want to use as a key in dictionary. The following wouldn’t be so common and only occur rare but it’s a possibility that you would also face the same situation so I came to share the same with you guys.

Problem: Now here the trouble starts. If you use generic list as key the default equality comparer checks for default has and simple object reference equality in Dictionary for keys. Now for two similar lists with similar underlying items would result in getting those two lists as different items. Which means you can add the two lists with similar items in Dictionary as a key with no objection. But what is benefit of using Dictionary then?

Solution: There’s an overload of constructor of Dictionary which accepts the custom Equality comparer for keys. So I’ve created custom equality comparer and it was also tricky to write that custom comparer.

So implementation of the custom equality comparer would look something like:

public class ListComparer<T> : IEqualityComparer<List<T>> where T:class 
{
    public bool Equals(List<T> x, List<T> y)
    {
        if (x.Count == y.Count)
        {
            for (int i = 0; i < x.Count; i++)
            {
                // Compare the objects based on values
                if (!(x[i] as T).PublicInstancePropertiesEqual(y[i] as T))
                {
                    return false;
                }
            }
        }
 
        return true;
    }
 
    public int GetHashCode(List<T> obj)
    {
        int hash = 19;
 
        foreach (T t in obj)
        {
            foreach (var objProperty in t.GetType().GetProperties())
            {
                if (objProperty.GetType().IsClass)
                {
                    hash ^= (hash * 31) + objProperty.SafeGetHashCode();
                }
                else
                {
                    hash ^= (hash * 31) + objProperty.GetHashCode();
                }
            }
        }
 
        return hash;
    }
}

Now why I have to write so much custom code in the Equals and GetHashCode method. If I use simple and direct solution then these list will always be different. So I have to XOR the hashcode of underlying items in both lists to get the hashcode based on the items rather than list reference. I found dealing with Hashcode from John Skeet’s post on stackoverlflow.


For equals method, I need to compare the values of the public properties of the list items as the reference would be different so again we felt into the same situation. But after comparing the values and hashcode individually for each item of list we can ensure if we’re not adding similar stuff again and again in the dictionary.


Here’s the Extension methods used in the custom Eqality comparer.



public static class EqualityExtension
{
    public static int SafeGetHashCode<T>(this T value) where T : class
    {
        return value == null ? 0 : value.GetHashCode();
    }
 
    public static bool PublicInstancePropertiesEqual<T>(this T self, T to, params string[] ignore) where T : class
    {
        if (self != null && to != null)
        {
            var type = typeof(T);
            var ignoreList = new List<string>(ignore);
            var unequalProperties =
                from pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                where !ignoreList.Contains(pi.Name)
                let selfValue = type.GetProperty(pi.Name).GetValue(self, null)
                let toValue = type.GetProperty(pi.Name).GetValue(to, null)
                where selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue))
                select selfValue;
            return !unequalProperties.Any();
        }
        return self == to;
    }
}

Hope you enjoyed the article.


For complete code sample download it form here.


References:

Thursday, 3 October 2013

How to hard reset the Canvas 4 Android

I’ve been using the Micromax Canvas4 from few months. There was an update from Gmail app and I downloaded and installed it. Then It asked me to “AutoSyncOption” to set to “ON” and I clicked “OK”. Later the device was in a restart loop after every 3-4 second. It’s like a mess for me as I bought it recently. Later I had to hard reset the device to factory setting and wiped all the data. Then It worked like a charm. I’ll share the steps but do it at you own risk but it worked for me.

How to Hard Reset the Canvas 4 Android device:

1. Switch off the device and then Boot it with holding volume up + volume down + unlock key together.

image

2. Now it will start booting when I vibrates first time release the key and It’ll start in the boot mode.

3. Now select the RecoveryMode. You can navigate through the option via volume up & down key and select the option by “Option/Menu”  button.

image

4. It’ll further go to another option menu. Now navigate to select the Wipe user data/Factory Reset option and select ok by Menu key.

5. Now this will start restoring to it’s factory setting*(state of the device when you purchased it).

6. When the reset will finish it’ll go back to the menu again. Now navigate to the Restart the device by selecting Restart option and click ok.

Now your device will be restarted and will be running again.

Warning/Disclaimer: Do this at your own risk. It worked perfectly for me.