Saturday, December 10, 2011

31 Days of Testing—Day 10: Mocking Out Dependencies

Updated: Index to all posts in this series is here!

Frankly, I’ve dreaded writing this post. Mocking is something that’s difficult to clearly get across, and the approaches and tooling for mocking vary perhaps even more widely than those for testing frameworks. There’s also an extraordinary range of terms people use to describe subtly different aspects of mocking—because we software folks don’t have enough confusing terminology in our lives already.

While I’m being specific with a mocking implementation in this post, it’s important that you keep focused at the higher level of the concepts I’m trying to get across. Look to the broad concepts and go do more exploration in the mocking tools and approaches specific to your platform.

Enough disclaimers. Let’s roll.

Why Mock?

In testing, mocking is a technique to let you cheat your system to isolate away dependencies external to the area of code you're trying to test. This is particularly important in unit testing where you want to focus on one small portion of your system—and you can’t do that if you’re having to deal with calls to external services, databases, security providers, etc.

Let’s have a look at one example. Below is some code for updating an employee’s information. This sort of action can be quite sensitive, especially since there is privacy and salary information involved. Ergo, you want to ensure there’s very solid security around this use case. My example below uses a security provider service which checks the current user and sees whether that user is permitted to do the specific actions on the target employee.

public class EmployeeUpdater
{
    private readonly IUpdateEmployeePermissible _updateEmployeeSecurityProvider;
 
    public EmployeeUpdater(
        IUpdateEmployeePermissible updateEmployeeSecurityProvider)
    {
        _updateEmployeeSecurityProvider = updateEmployeeSecurityProvider;
    }
 
    public Employee UpdateEmployeeRate(Employee targetEmployee, float newRate)
    {
        Employee updatedEmployee;
        if (_updateEmployeeSecurityProvider.CanUpdateEmployeeRate(targetEmployee.EmployeeId))
        {
            updatedEmployee = new Employee(targetEmployee.EmployeeId, targetEmployee.FirstName
                                           targetEmployee.LastName,
                                           targetEmployee.Address, newRate);
        }
        else
        {
            throw new SecurityException(
                "Invoking user doesn't have permissions to update target target employee. "
                + targetEmployee);
        }
        return updatedEmployee;
    }
}

I’m leaving out the implementation details for the security provider in an attempt to keep this as readable as possible. What’s important is an external (to this class) service figures out whether or not the current user can modify the target employee.

Design Impacts

Depending on your tool and platform, mocking may impact how you design your system. Note the security provider is passed in to the EmployeeUpdater’s constructor. Injecting dependencies this way, or through some form of setter, is an extremely preferred design approach for many reasons.

First, the EmployeeUpdater shouldn’t have to know how to create anything. Single Responsibility Principle says this class should know how to do its job really well, and not worry about other things. If the manner of creating a new security provider changed, then we'd have to modify the EmployeeUpdater, too. That’s nuts. Let things get built elsewhere and simply passed in to objects that need them.

Secondly, injecting the dependency to the class gives us a seam where we can substitute the real item with a fake one. We can use mocking tools, or just flat code, to create that faked out item and pass it to the portion of the system we’re trying to test.

One more consideration for mocking which can impact your design: different mocking toolsets on different platforms have limitations around what sorts of objects/classes they’re able to work with. In the .NET world, for example, many mocking tools are unable to deal with static or concrete classes. You’ll need to provide interfaces or abstract implementations for the classes you’ll want to mock out. Some tools will deal with static classes, some will deal with concretes, some won’t at all, and then some platforms lend themselves to completely different approaches.

Simple Stub Mocks

There are a number of different types of mocked objects. Mocked objects may have some behavior defined in them, or they may just be empty shells which do nothing more than satisfy your test’s need to have something in the “shape” of the real object.

In my examples below I’m using RhinoMocks for .NET. RhinoMocks uses the term “stub” to refer to a mock with no behavior, and “mock” for a faked object which has some behavior defined for it. The first test I’ll show you simply checks that an Employee object is returned with the correct updated pay rate. I don’t want to deal with the external security provider on this; the test is solely focused on whether or not the update happens properly. Ergo, I want to decouple the system and ignore the real security provider—I just want that to tell the system, “Yes, the current user is authorized.”

[Test]
public void Updated_employee_has_correct_rate()
{
    int userId = 1;
    int oldRate = 5;
    int newRate = 10;
 
    var stubProvider = MockRepository.GenerateStub<IUpdateEmployeePermissible>();
    stubProvider.Stub(x => x.CanUpdateEmployeeRate(userId)).Return(true);
 
    Employee current = new Employee(userId, "Jim", "Holmes", "Doghouse", oldRate);
    EmployeeUpdater updater = new EmployeeUpdater(stubProvider);
 
    Employee updated = updater.UpdateEmployeeRate(current, newRate);
 
    Assert.AreEqual(updated.HourlyRate, newRate);
}
The first statement in this test creates a stub of the security provider as defined by the interface IUpdateEMployeePermissible. (Dear .NET folks: can we please lose the last vestige of the silly Hungarian notation and just drop the “I” from interface names?).  The second statement defines an implementation that says “Whenever your method CanUpdateEmployeeRate is called, return true.”

Next we create an Employee object as test data and an EmployeeUpdater to actually test. Note that we pass in our stubbed out provider to the constructor. The EmployeeUpdater will now use the fake provider we created earlier.

The rest of the test is straight forward: invoke the method, check the results.

Because we’re using a stub, the fake provider won’t even care if we invoke CanUpdateEmployeeRate with a bogus ID. It will simply return true regardless of when or how it’s invoked.

Mocks With Behaviors

Now for the next test. We want to ensure that our security provider’s CanUpdateEmployeeRate is always invoked—this is a critical part of our overall business rules to ensure proper security for updating employees, after all.

What would happen if someone was working on the CanUpdateEmployeeRate method and commented out the security check for some troubleshooting, then mistakenly checked that in to source? You’d completely bypass the security check in production. Ick. Like that sort of thing never happens…

Mocking frameworks generally provide you ways to deal with this sort of interaction. In RhinoMocks you can use a “mock” to handle this.

[Test]
public void Verify_security_provider_is_called()
{
    int userId = 1;
    int oldRate = 5;
    int newRate = 10;
 
    var mockProvider = MockRepository.GenerateMock<IUpdateEmployeePermissible>();
    mockProvider.Expect(x => x.CanUpdateEmployeeRate(userId)).Return(true);
 
    Employee current = new Employee(userId, "Jim", "Holmes", "Doghouse", oldRate);
    EmployeeUpdater updater = new EmployeeUpdater(mockProvider);
 
    Employee updated = updater.UpdateEmployeeRate(current, newRate);
 
    mockProvider.VerifyAllExpectations();
}

Several major differences here: First, we’re generating a Mock, not a Stub in the first real statement. Secondly, we’re calling mockProvider.Expect instead of .Stub. The Expect call sets an expectation that CanUpdateEmployeeRate will be called once with the specific value set in userId. The next several lines are all the same; however, the final statement in this method isn’t the usual Assert we associate with tests – it’s a call to the mocked out security provider’s VerifyAllExpectations method.

This final statement asks the mocked object to check whether or not the system under test did the things we expected it to. In this case, we expected the system under test to invoke the CanUpdateEmployeeRate method with a value of 1.

The verification will fail if the CanUpdateEmployeeRate wasn’t invoked at all, or if it was invoked with a value other than 1.

Mocking frameworks can provide a wide range of expectation checks. You can look to ordered expectations (method A called before method D), constraints (input value between x and z), and many other validations.

Tools for Creating Mocks

You might start to see that creating a series of mocks could be quite complex. For example, if my security provider depended on something else which in turn depended on something else, then I’d have a nasty tree of objects I needed to deal with. Tools exist in every platform to help ease this. Factory Girl in Ruby is one, StructureMap and Ninject in the .NET world are others.

Look up these approaches to help you ease the burden of dealing with complex object graphs both in your testing and production worlds.

Wrapping Up

This is an extremely simplistic, high-level view of mocking. My goal was to simply show where mocks might be used, and expose you to a few of the fundamental concepts around them. Mocks are an extremely powerful tool, but it’s extremely easy to use them too much, or in too confusing a manner. It’s also easy to end up testing the mock you just created instead of the system itself!

Don’t stop with this post. Go read more around mocks and figure out how they can help you better test your systems!

Friday, December 09, 2011

31 Days of Testing—Day 9: Readable Tests

Updated: Index to all posts in this series is here!

This post is an off-the-cuff tangential post based on some interesting comments to my previous posts on test fundamentals.

A couple folks commented on my use of C#’s “var” keyword, pointing out that it made the tests less readable in their view. I think it raises an interesting point of discussion that is an extremely large debate on the value of strict typing. I’m going to forgo that conversation, and instead try to focus down on readability of tests.

In the following test, what’s most important?

[Test]
public void Computing_with_40_hours_at_rate_5_returns_200()
{
    WageComputer computer;
    bool isHourlyWorker = true;
 
    var computedWages = computer.ComputeWages(40, 5, isHourlyWorker);
 
    Assert.AreEqual(200, computedWages);
}

This test is validating that the ComputeWages method is correctly working and returning the correct values for my inputs. This test isn’t looking to validate the return type. Frankly, I don’t care what the return type is. I’m more concerned that the algorithm is functioning properly.

If I’m only concerned about the value coming out of the method, then, quite frankly, anything extra at all on the left-hand side of that statement is pure noise to me. Look at these two different examples:

double computedWages = computer.ComputeWages(40, 5, isHourlyWorker);

var computedWages = computer.ComputeWages(40, 5, isHourlyWorker);

That’s how my mind looks at these sorts of things. Frankly, I’d be happier if the compiler just got rid of the entire type declaration. The compiler knows what the right-hand side is returning. Even “var” is just noise to me. Something like this would be a thing of beauty:

computedWages = computer.ComputeWages(40, 5, isHourlyWorker);

(By the way, that’s not my idea. My pal Leon Gersing put this idea in front of me during an interesting discussion several years back at a .NET training day we put on.)

Moreover, explicitly using strong typing makes your tests more brittle. If you ever change the return type from ComputeWages you’ll need to go back and update every test using that class. (In this case that’s a somewhat contrived example. Please look at the larger point here.)

If you feel the need to have a test specifically checking the return type, then write a separate test for that.

Carry this over to everything else about your tests. What’s noise? What’s really important? Can you easily grok a test you wrote three weeks ago? Three months ago?

No? Why not?

Great software engineers, or the latest trend of labeling folks who care as “craftsmen,” understand the criticality of writing code that’s easily readable.  Tests need to have the same care, because tests are production code.

Take a close look at what you really for your test and cut out everything else. It’s just noise.

Updated: By the way, in case you get put off my my frequently curmudgeonly sounding tone, I really do love this sort of feedback and questioning on my posts. I do not have all the answers. Your questions and points make me constantly re-evaluate how I’m doing things, and that’s a good thing! Please, keep up comments and questions. I love ‘em!

Thursday, December 08, 2011

31 Days of Testing—Day 8: Pay Attention to Your Tests’ Setup!

Updated: Index to all posts in this series is here!

In yesterday’s post I laid out some fundamentals of what a test looks like in C# with NUnit, plus how you’d go about running it and getting results. Keep in mind that while I’m using NUnit and C# to illustrate fundamentals for these few columns, the basic tenets apply regardless of your platform or testing framework/toolset.

Today I want to focus on handling setup conditions for your tests. In yesterday’s examples, every test created a new WageComputer instance. This sort of duplication gets tedious and can lead to more maintenance hassles since it violates the DRY principle (Don’t Repeat Yourself). If you scatter creation of prerequisite classes, services, data, etc. across multiple tests, you’ll have to go to those same multiple tests to fix busted instantiations when those prerequisites change.

Instead, look to push this sort of work off to a centralized location. In many cases, you can use your test framework’s features to do this. NUnit and many other frameworks support setup methods at the fixture and namespace scope. Moreover, you can have these setup methods run once per class/fixture, or once per test. This lets you have great control over where you create prerequisite objects, load/create data, etc.

Here’s how this looks in NUnit using my examples from the previous post:

[TestFixture]
public class When_working_with_an_hourly_worker
{
    private WageComputer computer;
    bool isHourlyWorker;
 
    [TestFixtureSetUp]
    public void Run_once_before_any_tests_run()
    {
        isHourlyWorker = true;
        computer = new WageComputer();
    }
    [Test]
    public void Computing_with_40_hours_at_rate_5_returns_200()
    {
        //Arrange
 
        //Act
        var computedWages = computer.ComputeWages(40, 5, isHourlyWorker);
 
        //Assert
        Assert.AreEqual(200, computedWages);
    }
    
    [Test]
    public void Computing_with_41_hours_at_rate_5_returns_207_5()
    {
 
    //Arrange
     
    //Act 
    var wages = computer.ComputeWages(41, 5, true);
 
    Assert.AreEqual(207.50, wages);
    }
 

The TestFixtureSetup attribute will cause the NUnit runner to execute the method Run_once_before_any_tests_run when this class/fixture is first loaded. We’ll stand up a new instance of the WageComputer and set isHourlyWorker true. This is very similar to a class constructor, but the lifecycle is managed by the test framework, not the .NET internals. (Which I couldn’t explain to you. Go ask Jon Skeet or Bill Wagner.)

There’s a similar attribute called SetUp which executes before each test. This is handy if you need to freshly initialize something before each test. (Remember, tests shouldn’t rely on any state set in another test.)

What gets set up may need to get torn down. Frameworks and tools generally support some form of TestFixtureTeardown or Teardown approach to clean up after each fixture or each test, respectively. These are great places to stuff transaction rollbacks to clean up after database interactions, for example.

This is a very simplistic, trivial example, but I’m sure you grok the general concept here. You can use fixture setup and teardown methods to deal with fixture-related prerequisites. Very handy.

Now for some important caveats.

While you want to avoid too much duplication, you can easily get carried away and overly clever with inheritance and abstraction of your setup actions—to the point where it gets extraordinarily difficult to understand what’s being set up where.

In a previous life I worked with an internally created test framework based off a Behavior Driven Development framework. We let ourselves get perhaps a little overly clever with our inheritance and setup chain, and it became very difficult to learn and understand. (OK, there’s no “perhaps” about it. We did, and I was a major part of letting that happen. Bad Jim. Bad Jim!)

Using some psuedo code, the inheritance and setup chain looked something roughly like this:

Integration_test  (Base)
  //sets up database
 
Functional_test (Inherits from Integration_test)
  //sets up browser, configures UI
 
Feature_test  (Inherits from Functional_test)
  //configures system
 
Module_test  (Inherits from Feature_test)
  //creates a module
 
 
//Now we get to the actual tests!
When_creating_something_as_regular_user  (Inherits from Module_test)
  //creates new user
  
  //FINALLY does some testing!

Imagine you’ve got a failure in a test. You could potentially have to walk back up four layers of inheritance to understand exactly what’s going on where. This is an overly clever approach to setup which makes understanding of your tests extremely difficult. Remember that code is read and re-read many more times than it’s written.

In these sorts of cases it’s OK to relax a bit on the Don’t Repeat Yourself principle. There’s an extremely applicable saying for this situation: “Keep your system DRY and your tests slightly moist.” What that means is, it’s OK to duplicate some setup steps in your tests if it makes the fixture/class/spec more understandable.

The Bottom Line

Leverage your testing platform/framework’s features for helping you get prerequisites for your tests set up, just don’t get so convoluted that you can’t easily understand what’s going on in the test when you open it up a couple weeks or months after you’ve written it.

Wednesday, December 07, 2011

31 Days of Testing—Day 7: Automated Test Basics

Updated: Index to all posts in this series is here!

I thought today’s post would be a good opportunity to lay out some fundamentals of automated tests work. The mechanics of test automation varies extraordinarily based on what platform you’re working on, and even within platforms you’ll see vastly differing approaches based on whatever testing framework/toolset you’re using.

Testing frameworks have a number of commonalities, regardless of platform and implementation. You’ll have a test runner which executes the tests. Test runners may live in the IDE you’re using to write your tests, they may be a separate GUI, or they may be a command line runner. Command line test runners make it possible to run your tests in a number of different environments such as a build or continuous integration server. The tests themselves will likely be organized, depending on the framework/tool, into classes, fixtures, scenarios, or something else. You generally point your test runner at these fixtures and the runner noodles out what tests are contained within those groups. The runner will execute all those tests and give you back a report on the pass/fail status.

Today’s column shows unit tests, but the general concepts apply to integration and functional tests too.

I’m going to be showing examples in C# with NUnit and RhinoMock, simply because that’s what I’m very comfy with. Yes, yes, we should all get out of our comfort zone and do things on other platforms, but the point of this series isn’t for you to watch me flail around while trying to learn new stuff… Smile

Some things to keep in mind as you read posts of mine which contain code:

  • I’m old school, although I try hard to keep up with new trends
  • I haven’t written system code in a long time, just test code. There’s a bit of a difference.
  • I am a starting point for your learning, not a destination. Look at my stuff, figure out what works and doesn’t, then go find other places to learn more.

The examples I’ll be using today are taken from the Unit Testing 101 talks I give. The examples aren’t *DD-ish because I want to focus on very fundamental pieces with out adding any methodology to the mix. Like I said, old school—but the foundational principles are critical and similar regardless.

Without further ado, part one, unit test basics. The system we’ll be testing is a simple payroll wage calculator method. It’s purposely not optimized or concisely written because I use it as a starting point for some refactoring, etc. (If you’ve interviewed with me for a job you’ve likely seen a variant of this…)

Here’s the method:

public float ComputeWages(float hours, 
                            float rate, 
                            bool isHourlyWorker)
{
    if (hours < 0)
    {
        throw new ArgumentException("Hours must be greater or equal to zero " 
            + hours);
    }
    float wages = 0;
 
    if (hours > 40)
    {
        var overTimeHours = hours - 40;
        if (isHourlyWorker)
        {
            wages += (overTimeHours*1.5f)*rate;
        }
        else
        {
            wages += overTimeHours*rate;
        }
        hours -= overTimeHours;
    }
    wages += hours*rate;
 
    return wages;
}

This method figures wages for hourly and salaried workers based on their status (hourly/salaried), number of hours worked, and their hourly rate. Salaried workers don’t get overtime; hourly get time-and-a-half for anything over 40 hours.  We also check for negative inputs around hours. There’ input guards we should handle, but again, this method purposely leaves off a number of things.

Let’s cover basic tests for an hourly worker first. Looking at the code we want to make sure we hit all the boundaries in this method. There’s a boundary for over/under 40 hours, so we’ll need values over and under that. I always like to specifically test zero as well, so we’ll want a value there. Finally, we’ve got a check for negative hours, so we’ll need that. Let’s just use five bucks per hour as a our rate to simplify things. Here are our input values and expected outputs.

Hours Rate Expected
0 5 0
40 5 200
41 5 207.50
-1 5 ArgumentException

Let’s start with the simple happy path test first.

I mentioned fixtures above as a container for individual tests. In NUnit you create a class and decorate it with the TestFixture attribute. Other frameworks work in a similar fashion. Mostly.

[TestFixture]
public class When_working_with_an_hourly_worker
{...

A test fixture should contain a logical group of individual tests. Styles of grouping and naming conventions vary dramatically between advocates of particular methodologies. I’m avoiding all that discussion here and just focusing on the fact a fixture holds tests. You need to figure out what works with your team in your environment on your project.

In NUnit a test is simply a method with public scope that’s decorated with a Test attribute:

[Test]
public void Computing_with_40_hours_at_rate_5_returns_200()
{...

Now it’s time to write the actual test. Patterns for writing tests vary with methodologies, but I think there’s a common pattern regardless: Arrange, Act, and Assert. You Arrange the things you need to run the test, you Act on the system you’re testing, and you Assert to see if your actual results are what you expected.

Asserts, regardless of how they’re named in your framework/tool, are simply equality checkers of one form or another. You’re checking two strings are the same, two integers have the same value, or two collections have the same values in the same order. You’re generally asserting these conditions are equal, although you’ve likely many options such as Assert.IsFalse(someBoolean), Assert.IsNotNull(somethingElse), etc.

Here’s what our actual test will look like:

[Test]
public void Computing_with_40_hours_at_rate_5_returns_200()
{
    //Arrange
    WageComputer computer = new WageComputer();
    bool isHourlyWorker = true;
 
    //Act
    var computeWages = computer.ComputeWages(40, 5, isHourlyWorker);
 
    //Assert
    Assert.AreEqual(200, computedWages);
}

The final statement in this test is the Assert: it’s comparing the expected value (200) to the actual value returned from the call to ComputeWages. You’ll continually hear the terms “expected” and “actual” in testing parlance.

I’ll use the JustCode test runner that lives within Visual Studio to run this test. Here’s what it looks like as a passing test:

TestRunner-Green

If I change the expected value in the test to an incorrect value, we’ll see what the failure looks like. Note the red colors and the detailed message on the right frame. Your test runner’s output likely varies, but the point is you get a clear failure and an exact reason why the test failed. In this case, the expected value was 201 (my manual hack) and the actual was 200.

TestRunner-Red

Really, the first three test cases are variants of this: input values and an expected output value. Let’s jump to the last of the test cases, where our expected result is an ArgumentException. Every testing framework should give you the ability to assert exceptions are happening as you expect. In NUnit that’s handled simply via an attribute. Here’s how that actual test looks:

[Test]
[ExpectedException(typeof(ArgumentException))]
public void Invoking_with_negative_hours_throws_ArgException ()
{
    WageComputer computer = new WageComputer();
    var wages = computer.ComputeWages(-5, 5, true);
}

You’ll note we’ve got some duplication in our two tests: we’re repeating the setup of our WageComputer class. This isn’t a huge code smell for two tests, but I’d rather not see us continue this needless duplication as we grow our tests out.

Tomorrow we’ll discuss how to deal with this situation by using setup methods, and we’ll cover their corresponding teardown equivalents. We’ll also dive in to data driven tests.

Subscribe (RSS)

The Leadership Journey