Using ExtensionMethods with Moq to Make Your Unit Tests More Readable

As you may have noticed from last week’s post I’ve been doing a lot of Unit Testing work recently. The product I’m working on is huge and very complex and this makes Unit Testing (as well as general coding) a real challenge. I’ve decided to write a more technical post this week focusing on a trick I’ve found which I believe really helps improve the quality of your tests.

One of the tools we’re using is Moq, a mocking framework (much like RhinoMocks or NSubstitute (one I’ve not used but comes recommended)).

One of the biggest challenges developers face when creating Unit Tests is maintaining readability as the test grows. Consider the following typical test

[Test]
public void TypicalTestSetup()
{
  // Arrange
  var mock = new Mock<IDataAccess>();
  mock.Setup(x => x.GetIDOfRowWithGuid(It.IsAny<Guid>())).Returns(12);
  mock.Setup(x => x.GetValueFromDatabase()).Returns(1701);
  mock.Setup(x => x.SaveValue(73)).Returns(36);
  var sut = new BusinessLogic(mock.Object); 

  // Act
  var result = sut.DoWork(7);

  // Assert
  Assert.Equals(42, result);
}

As the mock is an object there’s no reason you can’t create ExtensionMethods for them. If I create the following method

 

/// <summary>
/// Sets up the method GetIDOfRowWithGuid to return the value given
/// </summary>
public static void SetupGetIDOfRowWithGuid(this Mock<IDataAccess> mock, int value)
{
  mock.Setup(x => x.GetIDOfRowWithGuid(It.IsAny<Guid>())).Returns(value);
}

 This allows us to call the setup code much more succinctly

mock.SetupGetIDOfRowWithGuid(12);

Personally I also like to return the mock as part of the ExtensionMethod

/// <summary>
/// Sets up the method GetIDOfRowWithGuid to return the value given
/// </summary>
public static Mock<IDataAccess> SetupGetIDOfRowWithGuid(this Mock<IDataAccess> mock, int value)
{
  mock.Setup(x => x.GetIDOfRowWithGuid(It.IsAny<Guid>())).Returns(value);
  return mock;
}

Because this allows you to create more more fluent style setup instructions.

// Arrange
var mock = new Mock<IDataAccess>()
  .SetupGetIDOfRowWithGuid(12)
  .SetupGetValueFromDatabase(1701)
  .SetupSaveValue(73, 36);
var sut = new BusinessLogic(mock.Object);			

This, in my opinion is far more readable, simplifies your setup and can be used to create powerful, reusable setups and verifies.

Have you used ExtensionMethods with mocks? What other tips and tricks do you use to keep your Unit Tests in order?

Playing with Microsoft Cognitive Services

It’s time for a little fun – inspired by Martin Kearn‘s talk at DDDNorth I fired up the Microsoft Cognitive Services Website, signed up and got myself a key for the emotion API. It didn’t take me long to get up and running!

I tried briefly using the SDK library but found some trouble with strongly typed names, deciding the abandon that approach I used the method Martin recommends on his blog and simply downloaded the json myself and parsed it.

Here’s my code:

        var _apiUrl = @"https://api.projectoxford.ai/emotion/v1.0/recognize";

        using (var httpClient = new HttpClient())
        {
          httpClient.DefaultRequestHeaders.Add(&amp;amp;quot;Ocp-Apim-Subscription-Key&amp;amp;quot;, _apiKey);
          httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(&amp;amp;quot;application/octet-stream&amp;amp;quot;));

          //setup data object
          HttpContent content = new StreamContent(new MemoryStream(File.ReadAllBytes(filename)));
          content.Headers.ContentType = new MediaTypeWithQualityHeaderValue(&amp;amp;quot;application/octet-stream&amp;amp;quot;);

          //make request
          var response = await httpClient.PostAsync(_apiUrl, content);

          //read response and write to view
          var responseContent = response.Content.ReadAsStringAsync().Result;
          var objResponse = JsonConvert.DeserializeObject&amp;amp;amp;lt;RootObject[]&amp;amp;amp;gt;(responseContent);

          var image = Image.FromFile(filename);
          using (var gfx = Graphics.FromImage(image))
          {
            foreach (var face in objResponse)
            {
              gfx.DrawRectangle(new Pen(Color.Red, 5),
                new Rectangle(new Point(face.faceRectangle.left, face.faceRectangle.top),
                  new Size(face.faceRectangle.width, face.faceRectangle.height)));

              var text = this.GetText(face.scores);

              gfx.DrawString(text, new Font(FontFamily.GenericSerif, 64), new SolidBrush(Color.Red),
                face.faceRectangle.left + 24,
                face.faceRectangle.height + face.faceRectangle.top);
            }
          }
          this.pictureBox1.Image = image;
        }

I’m very impressed with how easy it is (in fact most of it’s being used to update the picture box in my little Winforms app!).

What do you think? Do I look about 65% surprised?

emotion_screenshot

What’s new (and cool) in C# 6?

Many of the improvements in C# 6 are based around Rosyln, rebuilding the compiler and making it much easier to write Visual Studio plugins and doing fancy compilation in our own applications. This is all very exciting stuff but it doesn’t really impact me day to day. There are however two little features which I am using every day and have already slipped into my standard syntax.

The Null Conditional Operator

The Null Conditional Operator is game changing. Last year we’d have to perform a series of null checks to ensure that we weren’t going to receive a NullReferenceException when accessing the child properties of an object.


if(user != null && user.Communication != null && user.Communication.PhoneNumber != null)

{

  user.Communication.PhoneNumber.Call();

}

However with the introduction of the ?. operator we can do this all in a single line.


user?.Communication?.PhoneNumber?.Call();

If the user has both a Communication object and a PhoneNumber then call them.

This becomes even more powerful when combined with our old friend the ?? operator.


var numberToCall = user?.Communication?.PhoneNumber ?? DEFAULT_CONTACT_NUMBER;

Now if user or Communication are null instead of throwing a NullReferenceException they will evaluate as null. Now if either user, Communication or PhoneNumber are null the entire statement will return the DEFAULT_CONTACT_NUMBER instead.

String Interpolation

The new String Interpolation change is so simple but I’ve found myself using it almost exclusively since it became available.

In the past we’d write


var myMessage = string.Format("Welcome back {0}", user.Salutation);

This was fine, perhaps a little clunky when you had a lot of stings to merge in but we were happy. That was until I discovered the new C# 6 String Interpolation!


var myMessage = $"Welcome back {user.Salutation}";

Not only is this more concise, but it also eliminates the frustration we’ve all experienced when mixing up the position of the arguments.

Two simple changes, two huge reasons to use C# 6 now!