Showing posts with label unit testing. Show all posts
Showing posts with label unit testing. Show all posts

ReSharper Shortcut for Context-Sensitive Unit-Test Running

For a keyboard shortcut to the context-sensitive ReSharper unit test runner (otherwise available via right-click > Run Unit Tests), map:

ReSharper.ReSharper_UnitTest_ContextRun

(Thanks to Clinton for mentioning it.)

What This Solves


The slowest way to select and run unit tests is to click the green-yellow bubbles in the left margin and pick "Run" (or "Append to Session" to collect a bunch of them to run).



From the right-click menu, the "Run Unit Tests" option will run a test if your cursor is in a test, all tests in a fixture if your cursor is outside a test but within the fixture, or all tests in a file if you're outside any fixtures.

Mapping the ReSharper.ReSharper_UnitTest_ContextRun to a keyboard shortcut achieves the context-sensitive behavior, mouse free. I chose Alt-T for mine, since that wasn't in use for anything else. (Have a nice strategy for picking unique keyboard shortcuts and remembering them? Please share in the comments.)

To Map the Shortcut


Tools > Options > Environment > Keyboard. In the "Show commands containing" textbox, enter some or all of the command, and select the command.



Set your focus to the "Press shortcut keys" textbox and type your shortcut just as if you were invoking it. If a command shows up in the "Shortcut currently used by" list, life will be simpler if you pick a different shortcut. When you have one you like, click "Assign" and "OK." Good to go!

Rhino Mocks Examples, with a fix

Jon Kruger created an excellent explanation of Rhino Mocks, using unit tests to demonstrate and illuminate the syntax and capabilities. (Found via @gar3t.) It needs one small correction, which I'd like to write about here so that I can link to and support Jon's work, and because it gives the opportunity to clarify a subtle distinction between mocks and stubs and verified expectations.

First, go check out Jon's code, then come back here.

The problem lies in the following test. I can comment out the part that looks like it is satisfying the assertions, yet the test still passes—a false positive.

[Test]
public void Another_way_to_verify_expectations_instead_of_AssertWasCalled()
{
  var stub = MockRepository.GenerateStub<ISampleClass>();
 
  // Here I'm setting up an expectation that a method will be called
  stub.Expect(s => s.MethodThatReturnsInteger("foo")).Return(5);
 
  //Sneaky Sharon comments out the "Act" part of the test:
  //var output = stub.MethodThatReturnsInteger("foo");
  //Assert.AreEqual(5, output);
 
  // ... and now I'm verifying that the method was called
  stub.VerifyAllExpectations();
}

In translation, that test says: Create a fake ISampleClass; set up an expectation that a method will be called; call that method do nothing; verify that your expectations were met (and flag the test as a failure if they weren't). Shoot. Worse than not having my expectations met is not realizing they're not being met. Reminds me of my college boyfriend.

There are two things to fix here. The first is that this test is a little solipsistic. If you create a mock, tell the mock to act, and verify things about the mock... all you're testing are mocks. Instead, you want your tests to exercise real code. The "system under test," i.e., the class being tested, should be part of your production code. Its dependencies are what get mocked, so that you can verify proper interactions with those dependencies. Let's fix the solipsism before going on to the second issue.

As originally written, the expectation would be satisfied by the "Act" (as in Arrange-Act-Assert) part of the test. It says, "Call this method. Did I just call this method? Oh, good." Instead, you want to ensure the system under test correctly interacts with its friends, using Rhino Mocks' AssertWasCalled and Expect methods. We need a real class that takes the stubbed class and calls a method on the stubbed class, and we'll write unit tests around the real class.

public class MyRealClass
{
  public void ActOnTheSampleClass(ISampleClass sampleClass)
  {
  }
}

Here's the re-written test, verifying how my real class interacts with the ISampleClass interface.

[Test]
public void Another_way_to_verify_expectations_instead_of_AssertWasCalled()
{
  var stub = MockRepository.GenerateStub<ISampleClass>();
  var systemUnderTest = new MyRealClass();
 
  // Here I'm setting up an expectation that a method will be called
  stub.Expect(s => s.MethodThatReturnsInteger("foo")).Return(5);
 
  // Tell the system to act (which, if it is working correctly, 
  // will call a method on the ISampleClass.
  systemUnderTest.ActOnTheSampleClass(stub);
 
  // ... and now I'm verifying that the method was called
  stub.VerifyAllExpectations();
}

This test will still pass, despite the fact that my real class does not currently call any methods on the ISampleClass interface. This points to the second issue to fix. In Rhino Mocks, expectations on stubs are not verified; only mocks are verified. If an object is created with GenerateStub instead of GenerateMock, then its VerifyAllExpectations method doesn't do anything. This is non-obvious because the AssertWasCalled and AssertWasNotCalled methods on a stub will behave the way you want them to.

In Rhino Mocks, a stub can keep track of its interactions and assert that they happened, but it cannot record expectations and verify they were met. A mock can do both these things.

That is how they are implemented in Rhino Mocks. If you were holding firm to the ideas in Fowler's Mocks Aren't Stubs article, I think stubs would implement neither VerifyAll nor AssertWasCalled. Semantically, verifying expectations and asserting interactions are synonymous, if you ask me; therefore, stubs shouldn't do either one.

Back to Jon Kruger's tests. If we call GenerateMock instead of GenerateStub, the test will fail properly with an ExpectationViolationException.

[Test]
public void Another_way_to_verify_expectations_instead_of_AssertWasCalled()
{
  var stub = MockRepository.GenerateMock<ISampleClass>();
  var systemUnderTest = new MyRealClass();
 
  // Here I'm setting up an expectation that a method will be called
  stub.Expect(s => s.MethodThatReturnsInteger("foo")).Return(5);
 
  // Tell the system to act (which, if it is working correctly, 
  // will call a method on the ISampleClass.
  systemUnderTest.ActOnTheSampleClass(stub);
 
  // ... and now I'm verifying that the method was called
  stub.VerifyAllExpectations();
}

Now that we're red, let's get to green. Change the system under test so that it does its job as expected.

public class MyRealClass
{
  public void ActOnTheSampleClass(ISampleClass sampleClass)
  {
    sampleClass.MethodThatReturnsInteger("foo");
  }
}

Wahoo, a passing test that we can rely on.

The two key points from this exercise are:
  1. Describing Rhino Mocks with unit tests is a cool way to explain a topic. Let's have more executable documentation, eh?
  2. Expectations on stubs aren't verified, so beware of falsely passing tests.

Refactoring Dinner: Interfaces instead of Inheritance

Last time, in Cooking Up a Good Template Method, I had a template method cooking our dinner. An abstract base class defined the template—the high level steps for preparing a one-skillet dinner—and a derived class provided the implementation for those steps. I'm currently reading Ken Pugh's Interface Oriented Design (more on that after I finish the book), and it got me thinking of a way to change the design to use interfaces instead of inheritance.

I think there's value in this refactoring because it allows future flexibility and testability. Let's stroll through it, and I welcome your thoughts about how (and whether) this improves the code.

Previously, we had a base class SkilletDinner, which was extended by variants on that theme, such as chicken with onions and bell peppers or the FancyBaconPankoDinner. (If I've learned one thing from my readership, it is that blog posts should mention bacon. Mm, crispy bacon.) As the first step in the refactoring, I'll create an interface, ISkilletCookable that provides the same methods that were previously abstract methods in SkilletDinner. By naming convention, the interface is prefixed with 'I' and is an adjective describing how it can be used (-able).
    4   public interface ISkilletCookable
    5   {
    6     void HeatFat();
    7     void SauteSavoryRoot();
    8     void SauteProtein();
    9     void SauteVegetables();
   10     void AddSauceAndGarnish();
   11   }


Next, I'll create a SkilletDinner constructor that accepts an ISkilletCookable, and change the SkilletDinner's Cook() method to ask that cookable to do the work. SkilletDinner no longer needs to be abstract.
    5   public class SkilletDinner
    6   {
    7     private readonly ISkilletCookable cookable;
    8 
    9     public SkilletDinner(ISkilletCookable cookable)
   10     {
   11       this.cookable = cookable;
   12     }
   13 
   14     public void Cook()
   15     {
   16       cookable.HeatFat();
   17       cookable.SauteSavoryRoot();
   18       cookable.SauteProtein();
   19       cookable.SauteVegetables();
   20       cookable.AddSauceAndGarnish();
   21     }
   22   }


Then, FancyBaconPankoDinner implements ISkilletCookable and provides implementations for each of the methods that will be called by the Cook() method.

The first benefit from this refactoring is flexibility. While FancyBaconPankoDinner could not have inherited multiple classes (no multiple inheritance in C#), it can implement multiple interfaces. For example, it could also implement the IShoppable interface, thereby providing a ListIngredients() method that would let me include it in my grocery list.

This refactoring also makes it easier for me to test the quality and completeness of my template method. I can verify—does it cover all of the requisite steps for cooking a skillet dinner?—by creating behavior-verifying tests that assess the SkilletDinner's interactions with the ISkilletCookable interface. When I'm writing unit tests for the SkilletDinner class, I want to test its behavior because the behavior is what's important.

To forestall objections, I tried writing a test around the old version, creating my own mock class that extends the old abstract SkilletDinner. It got pretty lengthy.
    4   public class SkilletDinnerSpecs
    5   {
    6     [TestFixture]
    7     public class When_told_to_cook
    8     {
    9       const string heatFatMethod = "HeatFat";
   10       const string sauteSavoryRootMethod = "SauteSavoryRoot";
   11       const string sauteProteinMethod = "SauteProtein";
   12       const string sauteVegetablesMethod = "SauteVegetables";
   13       const string addFinishingTouchesMethod = "AddFinishingTouches";
   14 
   15       [Test]
   16       public void Should_follow_dinner_preparation_steps_in_order()
   17       {
   18         var systemUnderTest = new MockSkilletDinner();
   19 
   20         var expectedMethodCalls = new List<string>();
   21         expectedMethodCalls.Add(heatFatMethod);
   22         expectedMethodCalls.Add(sauteSavoryRootMethod);
   23         expectedMethodCalls.Add(sauteProteinMethod);
   24         expectedMethodCalls.Add(sauteVegetablesMethod);
   25         expectedMethodCalls.Add(addFinishingTouchesMethod);
   26 
   27         systemUnderTest.Cook();
   28 
   29         Assert.AreEqual(expectedMethodCalls.Count, systemUnderTest.CalledMethods.Count, "Expected number of called methods did not equal actual.");
   30 
   31         for (int i = 0; i < expectedMethodCalls.Count; i++)
   32         {
   33           Assert.AreEqual(expectedMethodCalls[i], systemUnderTest.CalledMethods[i]);
   34         }
   35       }
   36 
   37       private class MockSkilletDinner : SkilletDinner
   38       {
   39         public readonly List<string> CalledMethods = new List<string>();
   40 
   41         protected override void HeatFat()
   42         {
   43           CalledMethods.Add(heatFatMethod);
   44         }
   45 
   46         protected override void SauteSavoryRoot()
   47         {
   48           CalledMethods.Add(sauteSavoryRootMethod);
   49         }
   50 
   51         protected override void SauteProtein()
   52         {
   53           CalledMethods.Add(sauteProteinMethod);
   54         }
   55 
   56         protected override void SauteVegetables()
   57         {
   58           CalledMethods.Add(sauteVegetablesMethod);
   59         }
   60 
   61         protected override void AddFinishingTouches()
   62         {
   63           CalledMethods.Add(addFinishingTouchesMethod);
   64         }
   65       }
   66     }
   67   }


In the new design, I can mock the ISkilletCookable interface with a mocking framework like Rhino.Mocks. The interface is easy to mock because interfaces, being the epitome of abstractions, readily lend themselves to being replaced by faked implementations. Rhino.Mocks takes care of recording and verifying which methods were called.
    7   public class SkilletDinnerSpecs
    8   {
    9     [TestFixture]
   10     public class When_told_to_cook
   11     {
   12       [Test]
   13       public void Should_follow_dinner_preparation_steps_in_order()
   14       {
   15         var mocks = new MockRepository();
   16         var cookable = mocks.StrictMock<ISkilletCookable>();
   17         var systemUnderTest = new SkilletDinner(cookable);
   18 
   19         using (mocks.Record())
   20         {
   21           using (mocks.Ordered())
   22           {
   23             cookable.HeatFat();
   24             cookable.SauteSavoryRoot();
   25             cookable.SauteProtein();
   26             cookable.SauteVegetables();
   27             cookable.AddSauceAndGarnish();
   28           }
   29         }
   30         using (mocks.Playback())
   31         {
   32           systemUnderTest.Cook();
   33         }
   34       }
   35     }
   36   }


The test relies on Rhino.Mocks to create a mock implementation of ISkilletCookable, and then verifies that the system under test, the SkilletDinner, interacts correctly with ISkilletCookable by telling it what steps to do in what order.

That test is quite cognizant of the inner workings of the SkilletDinner.Cook() method, but that's specifically what I'm unit testing: Does the template method do the right steps? I don't mind how the steps are done, but you have to start the onions before you add the meat, or else the onions won't caramelize and flavor the oil.

By the way, if you had previously found the learning curve for Rhino.Mocks' record/playback model too steep a hill to climb (or to convince your teammates to climb), check out Rhino.Mocks 3.5's arrange-act-assert style. It creates more readable tests, putting statements in a more intuitive order. I really like it. I could not, however, use it here because I have not found a way to enforce ordering of the expectations (i.e., to assert that method A was called before B, and to fail if B was called before A) in A-A-A-style. So we have a record/playback test, instead.

Here's a summary of the refactoring. I extracted an interface, ISkilletCookable, and composed SkilletDinner with an instance of that interface, liberating us from class inheritance. Because SkilletDinner is now given the worker it depends on (via dependency injection), I can give it a fake worker in my tests, so that my unit tests don't need to perform the time- and resource-consuming operation of firing up the stove. And I managed to write another blog post that mentions bacon. Mm, bacon.