Posts Tagged ‘Testing’

Simple mocking with RhinoMocks

Monday, January 19th, 2009

Mocking frameworks and me

Until recently, mocking frameworks never really clicked in my mind.  I understood their purpose, however the terminology really didn’t fit with the idea of mocking to me and the tentative grasp I had on the concept would fall apart when I tried to get the mocking framework up and running in my tests.  So for a while I was mocking by hand.   Recently, I have been using Rhino Mocks successfully.  It has finally made sense to me, and I will mock by hand no longer.

The biggest mistake that I made in trying to understand the Rhino Mocks framework was thinking that all the mocking framework was doing was playing stunt double for the object that it was mocking.  Rhino Mocks doesn’t just ’stand in’ for the object you wish to mock, it will verify that methods are called on that object, giving you additional testing power.   Once I understood this, it explained the replay and verify terminology I would see in the examples, and things started to fall into place.

Once I had my epiphany about the usage of Rhino Mocks, I went to use it and I was stymied again.  I saw that I needed to create a mock object from an interface, but how?   And what is the difference between a StrictMock and a DynamicMock?   It wasn’t until I read this that I was able to begin actually using the framework.

As it turns out, the difference between a StrictMock and a DynamicMock is pretty simple to understand.  As we have seen, a core concept is the recording, playback and verification of method calls on the mock objects.  Well what happens if your System Under Test calls a method on the mock object that the mock wasn’t expecting?  What happens in this situation is the difference between Static and Dynamic Mock objects.  A StrictMock is just that, strict.  If a method gets called on a strict mock that it wasn’t expecting, it will let you know with red.  Now the terminology here still get me sometimes.  I think of the opposite of strict to be lax, forgiving or maybe flexable.  Likewise, I think of the opposite of dynamic to be static.  In this case, the opposite of strict is in fact, dynamic.  If a method is called on a dynamic mock that you didn’t tell it to expect, it just keep trudging along.  That’s not to say that it will necessarily return somehting valid, but the fact that the method itself  was called isn’t going to turn your test from green to red.

Making a mockery

So how do you actually use this beast?  Well it’s quite simple really, once you have all the pieces in place.   Having an understanding of interfaces and dependency injection will help get you off the ground here.  Let’s set up a couple of classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class DeathTrap : IDrivable
{
  private int _speed;
  private bool _brakesFunctional;
 
  public DeathTrap()
  {
    _speed = 0;
    _brakesFunctional = true;
  }
 
  public void Accelerate(int amount)
  {
    _speed = _speed + amount;
    // Something really time consuming and irrelevant here
  }
 
  public bool Brake(int amount)
  {
    // Something really time consuming and irrelevant here
 
    if (amount == 21)
    {
      _brakesFunctional = false;
    }
 
    if (_brakesFunctional == false)
    {
      return false;
    }
    _speed = _speed - amount;
  }
}
 
public interface IDrivable
{
  void Accelerate(int amount);
  bool Brake(int amount);
}
 
public class Driver
{
  private IDrivable _prideAndJoy;
 
  public Driver(IDrivable prideAndJoy)
  {
    _prideAndJoy = prideAndJoy;
  }
 
  public void Go(int amount)
  {
    _prideAndJoy.Accelerate(amount);
  }
 
  public bool Stop(int amount)
  {
    return _prideAndJoy.Brake(amount);
  }
}

Ok so this is a basic driving game where a driver has a DeathTrap that implements IDrivable. If the driver tries to brake by 21 units the brakes will go out and will no longer function. So let’s test Driver and make sure it does what we would expect it to do. First let’s test that when we tell the driver to go, he goes.

1
2
3
4
5
6
7
8
9
10
11
12
[Test]
public void WhenITellADriverToGoTheCarWillBeAccelerated()
{
  mockery = new MockRepository();  //Create an object to hold and manipulate mocks.
  car = StrictMock<idrivable>();  //Tell Rhino Mocks to make a strict mock from the interface.
  driver = new Driver(car);  // inject the car into the driver via constructor.
 
  car.Accelerate(5);  // tell the mock to expect a method call to Accelerate with a value of 5.
  mockery.ReplayAll();  // switch the mocks to replay mode.
  driver.Go(5);   // The actual call.
  mockery.VerifyAll();  // verify that the expected call was in fact made.
}

As you can see there are a number of things happening here, but it really breaks down to the following.

  1. Setup Mock
  2. Hand the mock to the System Under Test
  3. Tell the mock what call to expect
  4. Flip the mock framework into replay mode
  5. Do the stuff you want to test
  6. Verify that the expected call was made

That wasn’t too bad. Let’s try another example. This one has a slightly different syntax. I could have used a StaticMock here, it really didn’t matter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Test]
public void WhenIPressTheBrakeWithAValueOfTwentyOneItWillReturnFalse()
{
  mockery = new MockRepository(); // Setup our mock repository
  car = DynamicMock<idrivable>();  //make the mock car
  driver = new Driver(car);  // inject car into our driver
 
  Expect.Call(car.Brake(21)).Return(false);  //tell our mock to return false when it gets a call to brake 21
  mockery.ReplayAll();  // switch to replay mode
  bool returned = driver.Stop(21);  // call the System Under Test
  mockery.VerifyAll();  // verify that the method on car was called
 
  Assert.False(returned);  // assert the return value is false
}

The primary difference here is that the method that we are calling returns a value this time. So we have to tell our mock what to return when the method is called. Notice that in both cases of this contrived example, by mocking the car we were able to do three important things.

  1. Isolate the behavior we were interested in.
  2. Ensure that the IDrivable returned the value we wanted.
  3. Avoided having to wait for Something really time consuming and irrelevant to happen.

I hope this helps get you off the ground with using a mocking framework. If I come across any further eureka moments I’ll be sure to post them. Enjoy!

Chores: A test driven website, part 2

Friday, January 9th, 2009

This is part of the Chores series of posts

In which I continue to build the chores website and demonstating how simple it is to use a test first methodology. To follow along, please see my previous post.

Doh! I forgot to commit!

When I left off, I had come to a natural stopping point. A place where I was shifting focus from features to unit testing. I like to make my commits when my tests are all passing, however if I’m implementing a new feature, I don’t apply this hueristic since completing a feature will span multiple units of work. So let’s commit this. First let’s see where I am:

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       features/
#       lib/
#       script/cucumber
nothing added to commit but untracked files present (use "git add" to track)

Ok, git sees that I’ve added cucumber to my rails app and that I have added a feature. Let’s add these changes to our commit.

$ git add .

and commit them

$ git commit -m "added feature to create chores"

and finally push a copy out to the repository I set up on my shared host.

$ git push origin master

there all set.

Routing to home

At this point I’m a little confused as to how to proceed test first. We have a failing feature. When I have a failing feature I like to start by making a test to simulate the same error. However in this case, that is difficult at best, and the failing feature has already told me what I need to do, which is create a home_controller

$ ruby script/generate controller Home
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/home
      exists  test/functional/
      create  app/controllers/home_controller.rb
      create  test/functional/home_controller_test.rb
      create  app/helpers/home_helper.rb

.. and map a route to it. To do that I open up my ./config/routes.rb file and add the following route. I like to get rid of the legacy routes so I’ll replace the entire text of the file with the following

[sourcecode language="ruby"]
ActionController::Routing::Routes.draw do |map|
map.root :controller => ‘home’
end

So what are these controllers and routes?

If you are new to Rails, you are probably wondering what we just did. The controller is the C in the MVC pattern that Rails uses. It's role is to handle web serving of the application. It's kind of like an office assistant for your application. It be able to handle frequent requests and delegate them to the proper subject matter expert. When a request comes in for a list of Widgets, it will go to the Widget model and ask it for a list of widgets and then pass that off to the user interface (view) to display in the browser. When the user interface passes it a bag of information and asks it to save the information, the controller will create an instance of the appropriate model from the bag of information and then tell the model it should save the information.

Controllers really shouldn't become too involved in the details, but should delegate well to the objects that know what they are doing. Rails have a nice script to generate controllers, which we used above. In this case we generated a home controller which we will use to handle requests for the application's home page or root.

The second thing we did is define a route. Routes are related to controllers, in that they show the framework how to translate a request such as http://www.exmaple.com/sprocket/new into a method call on a controller. In the case of the above url, it would call the method new on the sprocket controller. You can find your routes in config/routes.rb and view all of your current routes with the rake task

rake routes

On with the show!

Now let's go back to cucumber and see where we are.

$ cucumber features
Story:  Define chores  # features/define_chores.feature
As a parent
I want to define chores
So that I can assign them to my children
  Scenario: Creating a chore       # features/define_chores.feature:6
    Given I am on the homepage    # features/step_definitions/chores_steps.rb:1
      No action responded to index. Actions:  (ActionController::UnknownAction)

Ok, our route is now wired up nicely to the controller, but the home controller does not respond to index. Lets add this to the controller

[sourcecode language="ruby"]
class HomeController < ApplicationController
def index

end
end

and try cucumber again

$ cucumber features
Story:  Define chores  # features/define_chores.feature
As a parent
I want to define chores
So that I can assign them to my children
  Scenario: Creating a chore     # features/define_chores.feature:6
    Given I am on the homepage   # features/step_definitions/chores_steps.rb:1
      Missing template home/index.erb in view path c:/rails/chores/app/views: (ActionView::MissingTemplate)

Ah ha! We are making progress. Our request has passed through the controller and is now looking for a view to render. One thing that I would like to point out is that doing the development in this way really lays out how the pieces of Rails all fit together. Something that we wouldn't have seen if we had chosen to generate a scaffold or we built it piecemeal without the tests metering our pace.

Views

Views are what end up being displayed in the web browser, they are a sort of template. By default, erb will process the template in the context of your request and output the dynamic content. Pretty cool stuff, and it gives you great control over your output.

Well what are we waiting for, let's make a view.

$ touch app/views/home/index.html.erb

In windows you can use your IDE or folder browser to create the file.

$ cucumber features
Story:  Define chores  # features/define_chores.feature
Story:  Define chores
As a parent
I want to define chores
So that I can assign them to my children
 
  Scenario: Creating a chore                          # features/define_chores.feature:6
    Given I am on the homepage                        # features/step_definitions/webrat_steps.rb:6
    When I follow "Add Chore"                         # features/step_definitions/webrat_steps.rb:18
      Could not find link with text or title or id "Add Chore" (Webrat::NotFoundError)
      (eval):2:in '/^I follow "([^"]*)"$/'
      features/define_chores.feature:8:in 'When I follow "Add Chore"'
    And I fill in "chore[name]" with "My first chore" # features/step_definitions/webrat_steps.rb:22
    And I press "Add"                                 # features/step_definitions/webrat_steps.rb:14
    Then I should see "Chore added."                  # features/step_definitions/webrat_steps.rb:93
    And I should see "My first chore"                 # features/step_definitions/webrat_steps.rb:93
 
1 scenario
1 failed step
4 skipped steps
1 passed step
rake aborted!

Hey look! Our first step has passed! Let's give ourselves a pat on the back. We have a website with a dynamic (albeit blank) homepage, that is tested.

Not all quotes are equal

I had an issue with my feature where the double quotes in my feature were translated automatically to open and closed style quotes. This was causing my steps not to match. If you find that you have a bunch of steps that are undefined at this point, that may be the issue.

Catch the passing step fever

The next step is one that is generated by webrat. It is looking for a link to follow called "Add Chore". The problem is that we didn't actually add the link, or anything else to the view. So let's update the view to read

[sourcecode language="ruby"]
<%= link_to "Add Chore", chore_path %>

and fire up cucumber

$ cucumber features
Story:  Define chores  # features/define_chores.feature
As a parent
I want to define chores
So that I can assign them to my children
  Scenario: Creating a chore      # features/define_chores.feature:6
    Given I am on the homepage    # features/step_definitions/chores_steps.rb:1
      undefined local variable or method 'chore_path' for #<actionView::Base:0x4baf67c> (ActionView::TemplateError)
      On line #1 of app/views/home/index.html.erb
 
      1: <%= link_to "Add Chore", chore_path %>
 
      app/views/home/index.html.erb:1

ok, we need to define resource for this, let's add a route and controller.

[sourcecode language="ruby"]
ActionController::Routing::Routes.draw do |map|
map.resources :chores
map.root :controller => 'home'
end

and

$ ruby script/generate controller Chores
      exists  app/controllers/
      exists  app/helpers/
      create  app/views/chores
      exists  test/functional/
      create  app/controllers/chores_controller.rb
      create  test/functional/chores_controller_test.rb
      create  app/helpers/chores_helper.rb
$ cucumber features
Story:  Define chores  # features/define_chores.feature
As a parent
I want to define chores
So that I can assign them to my children
  Scenario: Creating a chore    # features/define_chores.feature:6
    Given I am on the homepage   # features/step_definitions/chores_steps.rb:1
      chore_url failed to generate from {:action=>"show", :controller=>"chores"}
 - you may have ambiguous routes, or you may need to supply additional parameter
s for this route.  content_url has the following required parameters: ["chores",
 :id] - are they all satisfied? (ActionView::TemplateError)
      On line #1 of app/views/home/index.html.erb
 
      1: <%= link_to "Add Chore", chore_path %>

Dang it! still getting an error. Hmmm.. wait a minute. chore_path is generating a show action. That's not what we want to do. We want a new action to be RESTful or maybe an index action if we don't see REST in the future for this app. A quick consultation with the domain expert (me) says that there is no valid reason not follow the RESTful guidelines at this point so let's fix the home/index view to read.

[sourcecode language="ruby"]
<%= link_to "Add Chore", new_chore_path %>

cucumber says...

$ cucumber features
Story:  Define chores  # features/define_chores.feature
As a parent
I want to define chores
So that I can assign them to my children
  Scenario: Creating a chore   # features/define_chores.feature:6
    Given I am on the homepage   # features/step_definitions/chores_steps.rb:1
    When I follow "Add Chore"   # features/step_definitions/webrat_steps.rb:8
      No action responded to new. Actions:  (ActionController::UnknownAction)

Great! That fixed it. Now we need to make sure there is a new action on the chores controller.

class ChoresController < ApplicationController
  def new
 
  end
end
$ cucumber features
Story:  Define chores  # features/define_chores.feature
As a parent
I want to define chores
So that I can assign them to my children
  Scenario: Creating a chore    # features/define_chores.feature:6
    Given I am on the homepage    # features/step_definitions/chores_steps.rb:1
    When I follow "Add Chore"      # features/step_definitions/webrat_steps.rb:8
      Missing template chores/new.erb in view path c:/rails/chores/app/views: (ActionView::MissingTemplate)

cucumber likes it! But we still have an error. Let's create ./app/views/chores/new.html.erb as:

<% form_for(@chore) do |f| %>
  <%= f.error_messages %>
 
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
 
  <%= f.submit "Add" %>
  </p>
<% end %>

Hmmm.. wait we are getting ahead of ourselves. We need a model to be able to pass it to our view. We will have to generate that next.

Well we didn't get to Test::Unit this time around, but with a model in sight it's sure to be right around the corner. Until next time..

Using Factories for testing Castle ActiveRecord: Part 2 : Rearden

Thursday, January 8th, 2009

Earlier I posted about using factories for testing Castle ActiveRecord. I now have an update that I call Rearden.  Here is is:

using System;
using System.Collections.Generic;
using Castle.ActiveRecord;
 
namespace Rearden
{
    public delegate void ModifyClass(ActiveRecordClass instance, IDictionary overrides);
 
    ///
    /// This is a factory to create test objects for Castle ActiveRecord.
    ///
    public static class Factory
    {
        // overload to call without overrides
        public static ActiveRecordClass Init(ModifyClass modifyClass)
        {
            return Init(modifyClass, new Dictionary());
        }
 
        // instanciate and set values in ActiveRecordClass
        public static ActiveRecordClass Init(ModifyClass modifyClass, IDictionary overrides)
        {
            ActiveRecordClass instance = (ActiveRecordClass)Activator.CreateInstance(typeof(ActiveRecordClass));
            modifyClass(instance, overrides);
            return instance;
        }
 
        // overload to call without overrides
        public static ActiveRecordClass Make(ModifyClass modifyClass)
        {
            return Make(modifyClass, new Dictionary());
        }
 
        // create, save and flush ActiveRecordClass
        public static ActiveRecordClass Make(ModifyClass modifyClass, IDictionary overrides)
        {
            ActiveRecordClass instance = Init(modifyClass, overrides);
            ActiveRecordBase asBase = instance as ActiveRecordBase;
            asBase.SaveAndFlush();
            return instance;
        }
 
    }
 
}

Add the compiled Rearden Assembly to your Test Assembly and then create a Blueprint class:

using System;
using System.Collections.Generic;
using System.Text;
 
namespace Quality.Model
{
    public static class Blueprints
    {
        public static void Blueprint(Employee emp, IDictionary overrides)
        {
            emp.FirstName = overrides.ContainsKey("FirstName") ? (string)overrides["FirstName"] : Faker.NameFaker.FirstName();
            emp.LastName = overrides.ContainsKey("LastName") ? (string)overrides["LastName"] : Faker.NameFaker.LastName();
            emp.Xid = overrides.ContainsKey("Xid") ? (string)overrides["Xid"] : Faker.StringFaker.Randomize("X######");
        }
 
        public static void Blueprint(Foo foo, IDictionary overrides)
        {
            foo.Month = overrides.ContainsKey("Month") ? (DateTime)overrides["Month"] : new DateTime(Faker.NumberFaker.Number(2000, 2009), Faker.NumberFaker.Number(1, 12), 1);
            foo.Employee = overrides.ContainsKey("Employee") ? (Employee)overrides["Employee"] :  (Employee)Rearden.Factory.Make(Blueprint);
        }
    }
}

And now your test looks like:

        [Test]
        public void Can_find_by_Xid()
        {
 
            _values["Xid"] = "X123456"; // Dictionary
            Rearden.Factory.Make(Blueprints.Blueprint, _values);
            Employee fromDB = Employee.FindByXid("X123456");
            Assert.AreEqual("X123456", fromDB.Xid);
        }

Using Factories for testing Castle ActiveRecord

Wednesday, January 7th, 2009

Yesterday, John Nunemaker declared January to be Test Awareness Month in his post Test or Die.  The post is aimed at the Rails community but why stop there?  I’ve been working with Castle ActiveRecord today and since I’ve liked the plugin Machinist for Rails I decided to use the idea of using a factory to create test data.   The basic idea is that the factory class will create your record in the database that you would like to test.  There is a nice post on how to use it with Faker on the Advent2008 blog

I found a version of Faker for .Net and wired up a test factory for an ActiveRecord Employee class as follows.   I’m sure there is plenty of room for future refactoring and abasraction, but here is the basic idea:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class EmployeeFactory
    {
        // user set values
        private IDictionary _values = new Dictionary();
        public IDictionary Values
        {
            get {return _values;}
            set { _values = value; }
        }
 
        // clears user set values
        public void ResetValues()
        {
            _values.Clear();
        }
 
        // creates an instance with data but does not save it
        public Employee Init()
        {
            Employee emp = new Employee();
 
            emp.FirstName = _values.ContainsKey("FirstName") ? _values["FirstName"] : Faker.NameFaker.FirstName();
            emp.LastName = _values.ContainsKey("LastName") ? _values["LastName"] : Faker.NameFaker.LastName();
            emp.Xid = _values.ContainsKey("Xid") ? emp.Xid = _values["Xid"] : Faker.StringFaker.Randomize("X######");
 
            return emp;
        }
 
        //creates, saves and flushes
        public void Make()
        {
            Init().SaveAndFlush();
        }
 
        // creates x number of Employee records.
        public void Make(int times)
        {
            for (int i = 0; i < times; i++)
            {
                Make();
            }
        }
    }

This allowed me to write tests such as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
   public class EmployeeTestCase : AbstractModelTestCase
    {
        private EmployeeFactory _factory;
 
        [SetUp]
        public void SetUp()
        {
            _factory = new EmployeeFactory();
            PrepareScope();
        }
 
        [Test]
        public void Can_find_by_Xid()
        {
            _factory.Values["Xid"] = "X123456";
            _factory.Make();
            Employee fromDB = Employee.FindByXid("X123456");
            Assert.AreEqual("X123456", fromDB.Xid);
        }
 
        [Test]
        public void Xid_should_be_unique()
        {
            _factory.Values["Xid"] = "X123456";
 
            try
            {
                _factory.Make(2);
                Assert.Fail("Xid is not set to be unique");
            }
            catch (Castle.ActiveRecord.Framework.ActiveRecordException ex)
            {
                Assert.That(ExceptionMessageContains(ex, "Violation of UNIQUE KEY constraint"));
            }
        }
 
        [Test]
        public void Search_Should_Search_Xid()
        {
            _factory.Values["Xid"] = "X123456";
            _factory.Make();
            _factory.ResetValues();
            _factory.Make();
 
            Employee[] emps = Employee.Search("X123456");
            Assert.AreEqual(1, emps.Length);
            Assert.AreEqual("X123456", emps[0].Xid);
        }
 
        [Test]
        public void Search_Should_Search_LastName()
        {
            _factory.Values["LastName"] = "MyLast";
            _factory.Make();
            _factory.ResetValues();
            _factory.Make();
 
            Employee[] emps = Employee.Search("MyLast");
            Assert.AreEqual(1, emps.Length);
            Assert.AreEqual("MyLast", emps[0].LastName);
        }
 
        [TearDown]
        public void TearDown()
        {
            DisposeScope();
        }
 
    }

I am looking to improve on this code as I use it, but I’m rather happy with how well it’s working so far.