Unit Test Private Methods in Abstract Classes

I was sharing what I’d learned about unit testing private methods with some co-workers, and the idea of testing a private method of an abstract class was presented.

PrivateObject deals with this handily by allowing you to specify the type being tested in one of its constructors.

Here’s a simple example. Consider we have an abstract class, Mammal, and a derived class, Human.

public abstract class Mammal
{
    private void SecretMammalStuff()
    {
    }
}

public class Human : Mammal
{
}

We can test Mammal’s private method by doing the following:

var human = new Human();
var po = new PrivateObject(human, new PrivateType(typeof(Mammal)));
po.Invoke("SecretMammalStuff");

If we don’t specify the PrivateType argument in the PrivateObject constructor, we’re not able to access the base class’s private methods. This is the key to testing private methods in an abstract class.

Advertisement

Retrieve Active Directory User Photos in C#

Newer versions of Office (2010+) use Active Directory to retrieve and display user photos. It’s a useful feature that also adds visual interest. I can look quickly at the thumbnails at the bottom of an email or meeting request in Outlook to see who’s invited; this is much faster than reading through the semi-colon delimited list of email addresses.

I’m working on a TFS application that has some custom views. I thought it would be cool to display the user as a thumbnail instead of simply using their name. Doing this will add some pizzazz and, ultimately, result in a cleaner UI since vertical space is more abundant in my layout–it is less costly for me to show a 50×50 thumbnail than to display a 20×100 textbox.

So how do we do it? Like many tasks, the .NET Framework makes it relatively easy for us once we know what we’re doing. Here are the steps:

  1. Bind to a node in Active Directory Domain Services with the DirectoryEntry class
  2. Use the DirectorySearcher class to specify a search filter and find the desired user
  3. Extract the image bytes from the user properties
  4. Convert the bytes to a usable format

The method below accepts a username parameter, looks it up in AD, and binds the thumbnail to an Image. (Note that this is a WPF application, which is why I convert to the BitmapImage class. You may want to convert to a different type, like System.Drawing.Bitmap.)

private void GetUserPicture(string userName)
{
    var directoryEntry = new DirectoryEntry("LDAP://YourDomain");
    var directorySearcher = new DirectorySearcher(directoryEntry);
    directorySearcher.Filter = string.Format("(&(SAMAccountName={0}))", userName);
    var user = directorySearcher.FindOne();

    var bytes = user.Properties["thumbnailPhoto"][0] as byte[];

    using (var ms = new MemoryStream(bytes))
    {
        var imageSource = new BitmapImage();
        imageSource.BeginInit();
        imageSource.StreamSource = ms;
        imageSource.EndInit();

        uxPhoto.Source = imageSource;
    }
}

Rotate an Image in WPF Using Just XAML

One of the things that came along with WPF was the ability to create animations declaratively in XAML. I wanted to create a working-in-the-background spinner for a WPF application I was working on, and I thought that it would be a breeze with such powerful capability. However, I had a surprisingly difficult time finding a nice, simple example on the internet!

After a lot of looking and a bit of tinkering, I was able to come up with a solution that I’m mostly satisfied with. It’s a little more verbose than I was hoping for, but it’s still a XAML-only solution, which is what I was ultimately seeking.

Some notes about the solution:

  • The CenterX and CenterY properties of the RotateTransform element must be half of the image to make it rotate around the center of the image. My image is 24×24, so the X and Y centers are 12 and 12, respectively.
  • The DoubleAnimation will run on an infinite loop from angle 0 to 360 over a 1 second duration.
  • The storyboard will be active while the image’s IsEnabled property is set to True.
<Image Source="gear_24x24.png" Height="24">
    <Image.RenderTransform>
        <RotateTransform CenterX="12" CenterY="12" />
    </Image.RenderTransform>
    <Image.Style>
        <Style>
            <Style.Triggers>
                <Trigger Property="Image.IsEnabled" Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation
                                    Storyboard.TargetProperty="RenderTransform.Angle"
                                    From="0"
                                    To="360"
                                    Duration="0:0:1"
                                    RepeatBehavior="Forever" />
                            </Storyboard>
                        </BeginStoryboard>
                    </Trigger.EnterActions>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Image.Style>
</Image>

You could also extract the animation code away into a resource. This will improve reusability and keep your XAML cleaner if you have multiple spinners, but it’s more of a preference when dealing with a single spinner.

<Window.Resources>
    <Style x:Key="Spinner" TargetType="Image">
        <Setter Property="Height" Value="24" />
        <Setter Property="Image.RenderTransform">
            <Setter.Value>
                <RotateTransform CenterX="12" CenterY="12" />
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation 
                                        Storyboard.TargetProperty="RenderTransform.Angle" 
                                        From="0" 
                                        To="360" 
                                        Duration="0:0:1" 
                                        RepeatBehavior="Forever" />
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid>
    <Image Source="gear_24x24.png" Style="{StaticResource Spinner}" />
</Grid>

This solution is based on this post.

Unit Testing and Private Methods

So you’re a TDD developer.  You code along merrily, writing failing unit tests, implementing them to a point of success, and then you refactor. But then, with no notice–WHAM–a private method. Now what!?

There are different schools of thought for this scenario. One camp says that if it’s not publicly exposed, you shouldn’t be testing it. I think that’s valid, but it’s equally valid to write test code for private methods. Just because a method’s private doesn’t mean it doesn’t deserve the same special attention. And just because I want to test a method that happens to be private doesn’t mean I want to expose it to the rest of the world! Let’s not worry about the debate for now. I’m going to show you how you can override private methods with Microsoft Fakes and how call private methods with Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.

Override private methods

Problem: You have a private method with behavior that’s disruptive to unit testing. Regardless of the cause of the disruption, you want to provide an alternate implementation.

Solution: Use Microsoft Fakes to shim the private method. (Need to know more about Fakes? Check out my tutorial!)

Here’s how you can do it:

  1. Create an instance of your class
  2. Create a shim from  your class
  3. Override the private method on the shim
  4. Invoke the test method

Here’s a code example:

[TestMethod]
public void SecretMethod_FunctionalityIsOverridden()
{
    using (ShimsContext.Create())
    {
        var target = new FileReader("foo");
        var shim = new ShimFileReader(target);

        bool calledShimMethod = false;
        shim.SecretMethod = () => 
        {
            calledShimMethod = true;
            return "bar";
        };

        target.Read();

        Assert.IsTrue(calledShimMethod);
    }
}

Call private methods

Problem: You want to test a private method, but you can’t because it’s private.

Solution: Use Microsoft Test Framework’s included PrivateObject class.

The only thing I don’t like about PrivateObject is that it (presumably) uses reflection for method names, which means method names will be coded as strings with no compile-time checks. It’s very easy to use, though, and if you need to invoke a private method, I haven’t seen a better way to do it!

Here are the steps:

  1. Create an instance of your class
  2. Create a PrivateObject from your class
  3. Use the PrivateObject‘s Invoke method

And here’s the code:

[TestMethod]
public void SecretMethod_ReturnsHumorousMessage()
{
    var target = new FileReader("foo");
    var privateObject = new PrivateObject(target);
    var actual = privateObject.Invoke("SecretMethod");

    Assert.IsNotNull(actual);
}

Putting it all together (useless, but fun!)

I was able to verify both of these capabilities by writing a single unit test that overrides the private method, then calls the private method. Check it out:

[TestMethod]
public void SecretMethod_FunctionalityIsOverridden()
{
    using (ShimsContext.Create())
    {
        var target = new FileReader("foo");
        var shim = new ShimFileReader(target);

        // override the private method
        bool calledShimMethod = false;
        shim.SecretMethod = () => 
        {
            calledShimMethod = true;
            return "bar";
        };

        // call the private method
        var privateObject = new PrivateObject(target);
        var actual = privateObject.Invoke("SecretMethod");

        // assert that calling the private method
        // used the overridden implementation
        Assert.IsTrue(calledShimMethod);
    }
}

Get Work Item Hyperlinks from the TFS SDK

So you’ve created an awesome application that uses the TFS SDK to do all kinds of amazing and interesting data access, but it sure would be nice if you could click on a work item and open it in Team Web Access. You’d think this would be easily accomplished by appending “id=123” to the end of a query string. It’s not quite that straightforward, but the TFS SDK makes it pretty simple.

Here’s what you need to do:

  1. Add the appropriate TFS SDK references
    • Microsoft.TeamFoundation.Client
    • Microsoft.TeamFoundation.Common
    • Microsoft.TeamFoundation.WorkItemTracking.Client
  2. Instantiate a TfsTeamProjectCollection
  3. Retrieve the hyperlink service from the team project collection object
  4. Retrieve the hyperlink from the hyperlink service by providing a work item ID

Here’s what the code will look like:

var tpc = new TfsTeamProjectCollection(
    new Uri("http://OurTfsServer:8080/tfs/OurCollection"));
var linkService = tpc.GetService();
var uri = linkService.GetWorkItemEditorUrl(workItemId);

Regular Expression Searching in Visual Studio 2012

One of the recurring themes throughout the enhancements made in Visual Studio 2012 is improved searching. There are search boxes everywhere: in the title bar, in Solution Explorer, in Test Explorer… Everywhere!

In addition to making searches more accessible, they’ve also improved and simplified support for regular expressions. Regular expression searching is something that seemed like it existed in earlier version of Visual Studio, but they used their own, custom syntax which made it difficult and unintuitive to use.

In Visual Studio 2012, regular expression searching is extremely easy–relatively speaking–to use and very intuitive. When you press CTRL+F to bring up the search window, there’s a regular expression toggle button. Click the button, and your search criteria will be interpreted as a regular expression.

That’s all good and well, but what’s really cool is that you can use capture groups for finding and replacing. How many times have you had to go through a file making the same change based on a pattern over and over again?

Here’s an example of finding/replacing with regular expressions and capture groups:

Find:    var(?<x>dog|cat)
Replace: varSuper${x}

Will replace "vardog", "varcat", "varDOG"
With "varSuperdog", "varSupercat", "varSuperDOG"
But not replace "var dog" or "dog"

How cool is that!?

Read more about using regular expressions in Visual Studio here.

 

BDD in .NET with SpecFlow

Yesterday, I was invited to sit in on a demo/discussion about behavior-driven development (BDD) with SpecFlow. As a self-proclaimed unit test enthusiast, I was excited right away.

I’ve been doing my own, made-up version of BDD for a while. For example, I would have a function that calls several sub-methods. I’d mock the sub-methods and write tests to verify that the sub-methods were called. Then I’d move to the next “layer” by implementing the sub-methods in a similar fashion, repeating until I hit the bottom layer, where the actual work happens.

The problem with that approach is that all tested behaviors relate to the code and not business requirements or real-world scenarios. SpecFlow fixes that by using a Gherkin parser, allowing you to write test scenarios using business-readable, domain-specific language instead of code.

Here’s how you can get started with SpecFlow and Visual Studio. This tutorial is basically a modified version of the Project Setup Guide on the SpecFlow site. I ran into a couple issues with their tutorial, though, and their tutorial also doesn’t get much into implementing the application logic to fix unit tests once they’re generated.

Installing SpecFlow

SpecFlow is included in the Visual Studio Extensions Gallery, so installing it is a breeze.

  1. Open Visual Studio, and go to Tools > Extensions and Updates (Extension Manager in VS2010)
  2. Select the Online gallery
  3. Search for “SpecFlow”
  4. Install it!

Nice, now you’re ready to create your first test project.

Creating your first test project

SpecFlow tests are defined as “features” that have multiple scenarios. There is a small amount of project setup that needs to be done, but it’s not too bad and you can be up and running in just a few minutes.

  1. In Visual Studio, create a new Unit Test Project
  2. Install SpecFlow via NuGet
    • PM> Install-Package SpecFlow
    • I had to manually add the unit test provider to my app.config:
      <?xml version="1.0" encoding="utf-8"?>
      <configuration>
        <configSections>
          <section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
        </configSections>
        <specFlow>
          <unitTestProvider name="MsTest" />
        </specFlow>
      </configuration>
      
  3. Add a SpecFlow Feature to your project
  4. Generate Step Definitions by right-clicking in your newly created feature file

  5. Run your scenario by right-clicking in the feature file

    • Right-clicking in the feature and choosing Run SpecFlow Scenarios produced an error for me; I’ll be looking into this
    • I instead ran the unit tests as usual, and that worked fine
  6. Implement your code/step definitions until you have a passing test
    • I added my class-to-be-tested to the same file as my step definitions for brevity
      namespace adamprescott.net.SpecFlow.FirstProject
      {
          using Microsoft.VisualStudio.TestTools.UnitTesting;
          using System.Collections.Generic;
          using System.Linq;
          using TechTalk.SpecFlow;
      
          public class AddingMaching
          {
              private List<int> _numbers = new List<int>();
              private int _sum;
      
              public int Screen
              {
                  get { return _sum; }
              }
      
              public void EnterNumber(int num)
              {
                  _numbers.Add(num);
              }
              public void PressAdd()
              {
                  _sum = _numbers.Sum();
              }
          }
      
          [Binding]
          public class MyFirstFeatureSteps
          {
              private AddingMaching _addingMachine;
      
              public MyFirstFeatureSteps()
              {
                  _addingMachine = new AddingMaching();
              }
      
              [Given(@"I have entered (.*) into the calculator")]
              public void GivenIHaveEnteredIntoTheCalculator(int p0)
              {
                  _addingMachine.EnterNumber(p0);
              }
      
              [When(@"I press add")]
              public void WhenIPressAdd()
              {
                  _addingMachine.PressAdd();
              }
      
              [Then(@"the result should be (.*) on the screen")]
              public void ThenTheResultShouldBeOnTheScreen(int p0)
              {
                  Assert.AreEqual(p0, _addingMachine.Screen);
              }
          }
      }
      
    • The example shows a simple AddingMachine class with implemented steps to pass the default feature scenario
      Feature: MyFirstFeature
      	In order to avoid silly mistakes
      	As a math idiot
      	I want to be told the sum of two numbers
      
      @mytag
      Scenario: Add two numbers
      	Given I have entered 50 into the calculator
      	And I have entered 70 into the calculator
      	When I press add
      	Then the result should be 120 on the screen
      

That’s it! Now you should have a passing unit test that verifies the business-language requirement. You can add more scenarios to your feature file with different values and/or steps. Note that if you add more steps, you’ll probably need to re-generate step definitions. When you do this, only new step definitions will be generated. I recommend using the Copy methods to clipboard button in the Generate Step Definitions dialog to avoid overwriting the previously created and implemented step definitions.

Calculated Fields in Excel Pivot Tables

Pivot tables in Excel are awesome. I love them. Drag, drop, slice, and dice data in seconds. Create charts and graphs. Amaze your friends. It’s all about the pivot tables, baby!

Occasionally, you need more than just the data, though. You need to know the difference between two numbers, or the percentage of one number relative to another. This is where Calculated Fields come into play. I haven’t had a huge need for them in my previous pivot tabling, so I never really knew about them. When I needed a calculated field, I would create a column with the calculation I needed in my source data, and that worked fine.

Today, though, I accidentally discovered Calculated Fields, and they are sweet. All you need to do to create a Calculated Field is click on the Fields, Items, & Sets menu in the pivot table ribbon, and select Calculated Fields…. This will open a new dialog box that allows you to create a named field generated from a formula you create from the already-available pivot table fields.

Once created, your Calculated Field is available in the Pivot Table Fields list for you to use as data in your pivot table!

A “Shim-ple” Tutorial With Microsoft Fakes

I’ve written previously about using Rhino Mocks to write unit tests for hard-to-test code, but with the release of Visual Studio 2012 comes a new way to work around those not-so-test-friendly areas: Microsoft Fakes. For those of you familiar with Microsoft Research’s Moles project, Microsoft Fakes is simply the next version. Fortunately, Microsoft decided this offering was valuable enough to be included in the latest version of Visual Studio.

What is Fakes, you might be grammatically-awkwardly asking yourself. If I had to describe Microsoft Fakes in a sentence, I’d say this: Microsoft Fakes allows you to intercept any method call and provide a substitute implementation, including calls to static and non-virtual methods. Sounds powerful, right? Well, it is.

Getting started with MS Fakes is refreshingly easy, too. The integration with Visual Studio allows you to skip the hard parts and get right to the meat: hooking up the fakes to work with the code you’re testing. This post will show you how to write a unit test for a simple FileReader class that has a single Read method that–you guessed it–reads a file. I’ll walk you through the entire process from scratch to hopefully avoid any confusion. So let’s do it!

  1. Open Visual Studio 2012
  2. Create a new Visual C# Class Library project
  3. Create the FileReader class:
    namespace adamprescott.net.FakesTutorial
    {
        using System.IO;
    
        public class FileReader
        {
            private readonly string _path;
            public FileReader (string path)
    	    {
                _path = path;
    	    }
    
            public string Read()
            {
                using (var fs = new FileStream(_path, FileMode.Open))
                {
                    var sr = new StreamReader(fs);
                    return sr.ReadToEnd();
                }
            }
        }
    }
    
  4. Add a new Unit Test Project to the solution
  5. Add a reference to the Class Library project from the Unit Test Project
  6. Create the fakes assembly by right-clicking System in the Unit Test Project’s References and selecting “Add Fakes Assembly”
  7. Create the FileReaderTest class:
    namespace adamprescott.net.FakesTutorial.Tests
    {
        using Microsoft.VisualStudio.TestTools.UnitTesting;
    
        [TestClass]
        public class FileReaderTest
        {
            [TestMethod]
            public void TestMethod1()
            {
                using (Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create())
                {
                    // Arrange
                    const string path = "irrelevant";
                    const string expected = "contents";
                    var target = new FileReader(path);
    
                    // shim the FileStream constructor
                    System.IO.Fakes.ShimFileStream.ConstructorStringFileMode =
                        (@this, p, f) => {
                            var shim = new System.IO.Fakes.ShimFileStream(@this);
                        };
    
                    // shim the StreamReader constructor
                    System.IO.Fakes.ShimStreamReader.ConstructorStream =
                        (@this, s) => {
                            var shim = new System.IO.Fakes.ShimStreamReader(@this) {
                                // shim the ReadToEnd method
                                ReadToEnd = () => expected
                            };
                        };
    
                    // Act
                    var actual = target.Read();
    
                    // Assert
                    Assert.AreEqual(expected, actual);
                }
            }
        }
    }
    
  8. Run the test, and feel great about yourself!

There are a few important things to note about the use of Fakes in the test above. First, the fakes are wrapped in a ShimsContext. This makes sense since you’re intercepting system calls; you don’t want to accidentally affect other areas being tested outside of your test. Next, note that I’m using fakes to override two different constructors. I needed to override FileStream‘s constructor to open the file and StreamReader‘s constructor to read the file. In the StreamReader shim, I also provide a shim for the ReadToEnd method and configure it to return the fake text for my test. I probably could have opted to shim just FileStream, but the faking might be less straightforward since success would rely on knowing exactly which methods StreamReader will use when ReadToEnd is called.

For more information about getting started with Microsoft Fakes, check out this article at MSDN.

5 New Features I’m Looking Forward to in Visual Studio 2012

Last week, I attended a GANG meeting where Randy Pagels gave a presentation about what’s new in Visual Studio 2012. Prior to this, I had skimmed through the product guide, and I was expecting to see some nice new features. I didn’t expect to be blown away, but I left the meeting feeling completely geeked about the new version. And, since the RTM version was made available to MSDN subscribers last week, I wasted no time in getting it installed.

So what has me so stoked? Here’s a breakdown of the top 5 features that have me drooling:

  1. Code reviews
  2. Simplified code coverage (no more instrumenting DLLs!)
  3. Suspend/resume work
  4. Quick Launch
  5. Object Browser integration into Solution Explorer

I’ve only used VS2012 for a day or two now, and I haven’t had enough exposure to give an in-depth overview of these new features, yet. Unfortunately, the two that I’m most excited about–the new code review workflow and suspend/resume work–require a TFS upgrade, so I won’t be able to really test them until our IT department does that. I’m looking forward to using the other three right away, though!

Read more about What’s New in Visual Studio 2012 on MSDN.

%d bloggers like this: