Thursday, 31 January 2013

TfsBuildExtensions January Release

The TfsBuildExtensions project provides a number of frequently used activities for your team build template. So, if you are looking to extend or modify the build template for your team build, you can use the activities provided by the TfsBuildExtensions without needing to re-write activities of your own.

The latest release of project latest January release is now available. Amongst other improvements, it also contains the VSTest activity allowing you to run Visual Studio 2012 compatible unit tests with your TFS 2010 server. I blogged about it a few months ago.

Saturday, 12 January 2013

Of Microsoft Fakes, Internal Classes and Signing Keys


Recently there was a question raised in the community about using Microsoft fakes for internal classes and what should be specified in the InternalVisibleTo attribute in the AssemblyInfo file. There was some confusion so I thought it would be useful to write a detailed post about it.

For the purpose of this post, I created a class library (SimpleLibrary.dll) that contain two internal classes:

  1. TextFileReader: Responsible for reading contents from a given text file.
  2. Client: Uses the TextFileReader class.

We will create a simple unit test where we will use generated shims for the TextFileReader class, so that the test is not dependent upon the existence of a text file in the file system. The code for the two classes is as follows:

TextFileReader

namespace SimpleLibrary
{
using System.IO;

internal class TextFileReader{
internal string ReadFile(string fileName)
{
StreamReader file = null;
string text = string.Empty;
try{
file = new StreamReader(fileName);
text = file.ReadToEnd();
}
finally{
if (file != null){
file.Close();
file.Dispose();
}
}
return text;
}
}}

Client 


namespace SimpleLibrary
{
internal class Client {
private TextFileReader fileReader;

internal Client(TextFileReader fileReader){
this.fileReader = fileReader;
}

internal string TestMethod(string fileName){
return fileReader.ReadFile(fileName);
}
}}


As you can see, the TextReaderFile is an internal class with an internal method "ReadFile" and Client is another internal class that depends upon an instance of the TextReaderFile and uses it's "ReadFile" method.

SimpleLibrary.Test


Now lets create a unit test project to test our library, we will call it SimpleLibrary.Test. In order to test our internal classes in the unit test project, we will need to include the "InternalVisibleTo" attribute in the AssemblyInfo.cs file of the SimpleLibrary project as follows:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("SimpleLibrary.Test")]

Our unit tests can now see the internal classes and we can write unit tests for these. However, if we want to generate fakes for the internal classes, we will also have to include "InternalVisibleTo" attribute for the fakes assembly as well.

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("SimpleLibrary.Fakes")]

Adding the above attribute will allow the generated SimpleLibrary.Fakes class to view internal classes and methods.

Now, we can generate fakes for the library by right clicking on the reference to SimpleLibrary and clicking on the "Add Fakes Assembly" option.

Our very simple unit test is as follows:


namespace SimpleLibrary.Test
{  
using Microsoft.QualityTools.Testing.Fakes;  
using Microsoft.VisualStudio.TestTools.UnitTesting;  
using SimpleLibrary.Fakes;      

[TestClass]      
public class ClientTest  
{      
[TestMethod]
public void TestReadFile()
{
using (ShimsContext.Create()) {

// Arrange
ShimTextFileReader shim = new ShimTextFileReader();              
shim.ReadFileString = (filename) => { return "The file content."; };              
var target = new Client(shim.Instance);              

// Act              
var actual = target.TestMethod(@"C:\somefile.txt");

// Assert              
Assert.AreEqual("The file content.", actual);          
}      
}  }}


The test creates a shim of the TextFileReader class and uses it while calling the TestMethod in the client class.

Strong Named Assemblies:


Now, lets consider that the assembly SimpleLibrary has to be strongly named, so will have to sign the assembly. We do that by generating a key file "SimpleLibraryKey" and use it to sign the assembly as shown

Now compile the solution and you will get the following errors

"Friend assembly reference "SimpleLibrary.Test" is invalid. Strong-name assemblies must specify a public key in their InternalVisibleTo declarations."
"Friend assembly reference "SimpleLibrary.Fakes" is invalid. Strong-name assemblies must specify a public key in their InternalVisibleTo declarations."

To resolve this, we need to sign our SimpleLibrary.Test assembly and change our InternalVisible attribute in the SimpleLibrary project to include the PublicKey as shown below


[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("SimpleLibrary.Test, PublicKey=00240000048000009400000006020000002400005253413100040000010001006bec6379ed95c6180028a6bc797cdb256805f6dcb61cbdf4f3f3493c5c25efb411fa33472565a5b5426161fd16a6a10802ae710f2e6828d175a2346e33f3831520bcf00e8584919cdf34ed11e51bb988f624360aeadf9b4dc764adc8aeab9939ad209b35f17f2d63192288b0e9bbe5ac013c56d7575b9277cde19e1be7d74f8b")]

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("SimpleLibrary.Fakes, PublicKey=00240000048000009400000006020000002400005253413100040000010001006bec6379ed95c6180028a6bc797cdb256805f6dcb61cbdf4f3f3493c5c25efb411fa33472565a5b5426161fd16a6a10802ae710f2e6828d175a2346e33f3831520bcf00e8584919cdf34ed11e51bb988f624360aeadf9b4dc764adc8aeab9939ad209b35f17f2d63192288b0e9bbe5ac013c56d7575b9277cde19e1be7d74f8b")]

Please note that by default the generated SimpleLibrary.Fakes.dll assembly will be signed with the same key as used in the original class. If we want, we can also use a different key to sign our fakes assembly. Recompile the project and we got errors similar to


"'SimpleClient' is inaccessible due to its protection level...."

The key step here is to include the KeyFile attribute in the Compilation element of the SimpleLibrary.Fakes file. The attribute will look like following, where Key file is the name of the key file used for signing the assembly

<Compilation KeyFile="SimpleLibraryKey.snk" />

Please note that the key file for the fakes assembly can be different from the original one. As long, as you are specifying the PublicKey of the key file specified in the Compilation attribute in the InternalVisible attribute, your code will compile and you can fake the internal classes.


Update 30/01/2013:

I have received some feedback and stand corrected on the key is used by Microsoft Fakes. The default key used by Fakes will always be the one shown below

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("SimpleLibrary.Fakes, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e92decb949446f688ab9f6973436c535bf50acd1fd580495aae3f875aa4e4f663ca77908c63b7f0996977cb98fcfdb35e05aa2c842002703cad835473caac5ef14107e3a7fae01120a96558785f48319f66daabc862872b2c53f5ac11fa335c0165e202b4c011334c7bc8f4c4e570cf255190f4e3e2cbc9137ca57cb687947bc")]


My original understanding was that the key used by Micorosft Fakes is the same key that signs the assembly  it is faking. This is obviously not correct and this is mentioned clearly in MSDN http://msdn.microsoft.com/en-us/library/hh708916.aspx.  You can of course use a different key and and in that case the &ltCompilation KeyFile=""> would be required.

Thursday, 10 January 2013

Developer Productivity with Visual Studio 2012

It's been a fair few months that I have been using Visual Studio 2012 and I must admit that the VS2012 way of working is dawning on me. A lot of features have been moved around and it takes some time to get used to it especially the Team Explorer window. But, once you get the hang of it, you will find that it is a much more productive working environment than the previous versions of Visual Studios.

Below is a great video detailing reasons for the reshuffle in UI and some great tips about improving developer productivity. 


Given that most of the developers spend most of their working day using Visual Studio, I would encourage all to view this video.




Saturday, 5 January 2013

Mocking HttpWebRequest using Microsoft Fakes

In my last post, I detailed the use of  RegisterPrefix method of the WebRequest class to mock calls to HttpWebRequest. I also mentioned that an alternative mechanism to isolate calls to HttpWebRequest was to use the Shims feature in Microsoft Fakes Framework. In this post, I will demonstrate how to do so.

Microsoft Fakes provides two ways of achieving isolation of "code under test" from underlying assemblies namely Stubs and Shims. The Stubs feature generates a dummy class implementing the interface to be stub'ed out allowing you to specify responses made to different method calls in your code. Shims, on the other hand, divert calls within the code of the underlying classes to the code you have written in your definition of the Shim. I wrote a post about Microsoft Fakes sometimes ago.

Coming back to the topic, below is a class that makes a call to the web service.

namespace FakesClass
{
    using System;
    using System.Net;
    /// <summary>
    /// Sample web service client class
    /// </summary>
    public class WebServiceClient
    {
        /// <summary>
        /// Calls a web service with the given URL
        /// </summary>
        /// <param name="url">The web service's URL</param>
        /// <returns>True if the services responds with an OK status code (200). False Otherwise</returns>
        public bool CallWebService(string url)
        {
            var request = CreateWebRequest(url);
            var isValid = true;
            try
            {
                var response = request.GetResponse() as HttpWebResponse;
                isValid = (HttpStatusCode.OK == response.StatusCode);
            }
            catch (Exception ex)
            {
                isValid = false;
            }
            return isValid;
        }

        /// <summary>
        /// Creates an HttpWebRequest object
        /// </summary>
        /// <param name="url">The URL to be called.</param>
        /// <returns>An HttpWebRequest.</returns>
        private static HttpWebRequest CreateWebRequest(string url)
        {
            var request = WebRequest.Create(url) as HttpWebRequest;
            request.ContentType = "text/xml;charset=\"utf-8\"";
            request.Method = "GET";
            request.Timeout = 1000;
            request.Credentials = CredentialCache.DefaultNetworkCredentials;
            return request;
        }
    }
}
The CallWebService method takes in the url string of the web service to be invoked and returns true or false depending upon whether the HttpResponse has a status code of 200 (HTTP OK) or not. This is a very simple example. You can get your response object to return a response string of whatever your unit test requirements is.

Now that we have a class to unit test, I created a unit test project adding a project reference to the project containing the WebServiceClient class.

Once the unit test project is created, the next step is to generate Fakes class for the HttpWebRequest, HttpWebResponse and WebRequest class. Since, these class reside in the System namespace, the way to generate fake class is to right click on the System Reference and click on the option "Add Fakes Assembly" as shown:


Please note that to date this option (and Microsoft Fakes) is only available for the Ultimate edition of Microsoft Visual Studio 2012.

The "Add Fakes Assembly" option will add the following two assemblies as reference in your unit test project
  • mscorlib.4.0.0.0.Fakes
  • System.4.0.0.0.Fakes
and also add a folder called "Fakes" with the following two files added to it
  • mscorlib.fakes
  • System.fakes




The reason that there are two set of files are added to the solution is because the System namespace is implemented in two assemblies. Since, we are faking only classes in System.Net namespace, we can safely remove the reference mscorlib.4.0.0.0.Fakes and the file mscorlib.fakes. The final references looks as follows
The .fakes file contain details of the files that would be shim'ed or stubbed in the tests. Since, we want to use shim for WebRequest, HttpWebRequest and HttpWebResponse, change the contents of the System.fakes file to the following text.

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
    <Assembly Name="System" Version="4.0.0.0"/>
    <StubGeneration>
        <Clear/>
    </StubGeneration>
    <ShimGeneration>
        <Clear/>
        <Add FullName="System.Net.WebRequest!"/>
        <Add FullName="System.Net.HttpWebRequest!"/>
        <Add FullName="System.Net.HttpWebResponse!"/>
    </ShimGeneration>
</Fakes>
As you can see, we have cleared out all stub generation and added the three desired classes in the <ShimGenerate\> section. Now, we are all ready to use the generated shims in our unit tests.

The name convention that Microsoft Fakes uses for stubs and shims is Stub{ClassName} & Shim{ClassName} respectively so our shim'ed classes HttpWebRequest class will be called ShimHttpWebRequest class and so on.  The following unit test demonstrates using the Shims.

[TestMethod]
public void TestThatServiceReturnsAForbiddenStatuscode()
{
    using (ShimsContext.Create())
    {
        // Arrange
        var requestShim = new ShimHttpWebRequest();
        ShimWebRequest.CreateString = (uri) => requestShim.Instance;
        requestShim.GetResponse = () => { return new ShimHttpWebResponse() { StatusCodeGet = () => { return HttpStatusCode.Forbidden; } }; };
        var client = new WebServiceClient();
        var url = "http://testwebservice.mywebservice.com";
        var expectedResult = false;
        //Act
        bool actualresult = client.CallWebService(url);
        //Assert
        Assert.AreEqual(expectedResult, actualresult);
    }
}
Please note that the test makes a call to ShimContext.Create and creates objects of type ShimWebRequest and ShimWebResponse. Also, the call to ShimWebRequest returns a ShimHttpWebRequest object.

Updated 23/01/2013: Here is the link to the visual studio solution used in this post and my previous post about mocking HttpWebRequest. The solution contains two unit test projects for testing the same class, one illustrating the use of RegisterPrefix method and the other using the Shim feature of Microsoft Fakes.
 

Thursday, 3 January 2013

Mocking HttpWebRequest

In one of my recent assignments, I had a requirement to call an external web service. As I wanted to isolate calls to the web service from the functionality that handles the response, I was looking to find ways of mocking calls to the web service. My first thoughts were to create an "IHttpRequest" interface and to encapsulate all HttpWebRequest through this interface.

However, since the call to create an HttpRequest requires casting a WebRequest into an HttpWebRequest, using interface to mock calls to HttpRequest wasn't particular. Following is a typical code block of creating HttpRequest (Note the typecast to HttpWebRequest)


        private static HttpWebRequest CreateWebRequest(string url)
        {
            var request = WebRequest.Create(url) as HttpWebRequest;
            request.ContentType = "text/xml;charset=\"utf-8\"";            
            request.Method = "GET";
            request.Timeout = 1000;
            request.Credentials = CredentialCache.DefaultNetworkCredentials;
            return request;
        }

Looking closely at the WebRequest class, I realised that the class is implementing the Factory Method pattern. To create your own factory class, all that is needed to be done is to create a class that implements the IWebRequestCreate interface and register this class to be used for the Urls in your web request calls. 

My testing requirements were to return different HttpStatusCodes, so my factory class looked as follows. Please note that I am using Moq for mocking.


    /// <summary>
    /// A custom implementation of IWebRequestCreate for Web Requests.
    /// </summary>
    /// <summary>A web request creator for unit testing.</summary>
    public class CustomWebRequestCreate : IWebRequestCreate
    {
        /// <summary>
        /// The web request.
        /// </summary>
        private static WebRequest nextRequest;

        /// <summary>
        /// Internally held lock object for multi-threading support.
        /// </summary>
        private static object lockObject = new object();

        /// <summary>
        /// Gets or sets the next request object.
        /// </summary>
        public static WebRequest NextRequest
        {
            get
            {
                return nextRequest;
            }

            set
            {
                lock (lockObject)
                {
                    nextRequest = value;
                }
            }
        }

        /// <summary>
        /// Creates the new instance of the CustomWebRequest.
        /// </summary>
        /// <param name="uri">The given Uri</param>
        /// <returns>An instantiated web request object requesting from the given Uri.</returns>
        public WebRequest Create(Uri uri)
        {
            return nextRequest;
        }

        /// <summary>
        /// Creates a Mock Http Web request
        /// </summary>
        /// <returns>The mocked HttpRequest object</returns>
        public static HttpWebRequest CreateMockHttpWebRequestWithGivenResponseCode(HttpStatusCode httpStatusCode)
        {
            var response = new Mock<HttpWebResponse>(MockBehavior.Loose);
            response.Setup(c => c.StatusCode).Returns(httpStatusCode);

            var request = new Mock<HttpWebRequest>();
            request.Setup(s => s.GetResponse()).Returns(response.Object);
            NextRequest = request.Object;
            return request.Object;
        }
    }

Having got this class, the setup code in my unit tests would look as follows

WebRequest.RegisterPrefix("http://testService.mywebservice.com", new CustomWebRequestCreate());

CustomWebRequestCreate.CreateMockHttpWebRequestWithGivenResponseCode(HttpStatusCode.OK);

Or

WebRequest.RegisterPrefix("http://testService.mywebservice.com", new CustomWebRequestCreate());            CustomWebRequestCreate.CreateMockHttpWebRequestWithGivenResponseCode(HttpStatusCode.Forbidden);

Just makes creating unit tests so much easier for a variety of response codes. You can extend the CustomWebRequest to mock your responses as you like.


Microsoft Fakes and .Net 4.5. 


The WebRequest class is extended in .Net 4.5 to include new CreateHttp(Uri) and CreateHttp(String) methods, each of which returns an HttpWebRequest object. So there is no need to have a cast. Also, the "Shims" functionality in Microsoft Fakes allows to describe the behaviour of .Net classes. So, HttpWebRequest.GetResponse() method can be "Shim'ed" out to return a response of your choice. This follow up post describes how to use fakes to isolate calls to HttpWebRequests.