mocking in context specifications

In a previous set of posts I've explored a user story which has led to the creation of a BalancePresenter class for use in my MVP pattern. I now continue with this development and start this post with a new context - when I initialise a presenter I want it to go and get the current balance from the repository.
I write my specification as follows:

[Observations] 
public class when_initialising_a_balance_presenter : BalancePresenterSpecification  
{ 
    private context c = () => repository.Stub(r => r.GetCurrentBalance())
                                                   .Return(balanceUsedInObservations); 

    private because b = () => sut.Initialise(); 

    [Observation] 
    public void should_obtain_current_balance_from_the_repository() 
    { 
        repository.was_told_to(r => r.GetCurrentBalance()); 
    } 
}

I've set a context for my observations where I want to stub out a method on the mock repository object so that I can return a balance for the new method "GetCurrentBalance". It is using a protected member of the base class that is shown in a moment.

The above code is also using a delegate of type "because" which operates in a similar manner to the context delegate but essentially forms the "Act" part of the Arrange-Act-Assert syntax that this library enables - this delegate is performed before each observation that will be made.

I'm also using a new extension method in the library that wraps Rhino Mock call assertions - "was_told_to" - behind the scenes it uses the AssertWasCalled() method in the mocking framework.

To get this to compile I now need to create placeholder methods - an Initialise() on the BalancePresenter and a GetCurrentBalance on the IRepository. On the MemoryRepository class that implements it I return null.
All have no implementation in them to enable me to run the test, but before I do that I want to look at revising the base BalancePresenterSpecification and I add code as follows:

public class BalancePresenterSpecification : 
            observations_for_a_sut_without_a_contract<BalancePresenter> 
{ 
    protected static Double amount; 
    protected static Balance balanceUsedInObservations; 
    protected static DateTime date;  
    protected static IRepository repository;

    private context c = () => 
    { 
        amount = 15.45; 
        date = DateTime.Parse("01/01/2009"); 
        balanceUsedInObservations = new Balance(amount, date); 

        repository = the_dependency<IRepository>();   
     }; 
}

I've added a context that will run before the creation of my sut (system under test of type BalancePresenter - see earlier posts for more information on this). I've done so in the base class because I know that I will need the dependencies and the balance is future contexts (I'm retrospectively posting this from a later stage in my code where I added it on progressively and see little point in regressing it just for this illustration!).

The library is automatically wiring the BalancePresenter up with its greediest constructor behind the scenes and generating proxies for each dependency required by that constructor.
I'm accessing this proxy class by calling "the_dependency" for the type that I want - IRepository. Under the covers the code for accessing the dependencies looks like this:

static protected Dependency the_dependency<Dependency>() where Dependency : class 
{ 
    if (has_no_dependency_for<Dependency>()) 
          dependencies[typeof (Dependency)] = an<Dependency>(); 

    return (Dependency) dependencies[typeof (Dependency)]; 
}

A dictionary of dependencies are maintained in the base class and if there isn't one present it creates one via "an" which is illustrated below:

static public InterfaceType an<InterfaceType>() where InterfaceType : class 
{ 
    return MockRepository.GenerateStub<InterfaceType>(); 
}

It simply wires up a mock object from Rhino Mocks on my behalf and all I need is that one line - great stuff.

When I run the tests I get a failure, which is the desired effect - I haven't implemented the code in the Initialise method yet. I now do that and it passes the test:

public void Initialise() 
{ 
    Balance balance = repository.GetCurrentBalance(); 
}

I can now add a new observation for my assertion:

[Observation] 
public void should_set_the_correct_balance_on_the_view() 
{ 
    balanceView.was_told_to(v => v.SetBalance(balanceUsedInObservations)); 
}

Again, this uses the "was_told_to" extension method but of interest here is the balance variable I am using in the lambda expression - not only will it verify that SetBalance is called, but it will also do a reference comparison on the argument for me. I can then ensure that the right balance reference is going out to the view. In order to support this I have to modify the base BalancePresenterSpecification:

public class BalancePresenterSpecification : 
            observations_for_a_sut_without_a_contract<BalancePresenter> 
{ 
    protected static Double amount; 
    protected static Balance balanceUsedInObservations; 
    protected static DateTime date; 

    protected static IBalanceView balanceView; 
    protected static IRepository repository; 

    private context c = () => 
    { 
        amount = 15.45; 
        date = DateTime.Parse("01/01/2009"); 
        balanceUsedInObservations = new Balance(amount, date); 

        balanceView = the_dependency<IBalanceView>(); 
        repository = the_dependency<IRepository>(); 
    }; 
}

I have a new protected member of type IBalanceView and I am assigning a value to this in the context by obtaining a proxy dependency for it. To get my code to compile I need to create a placeholder SetBalance() method on the IBalanceView interface.
When I run my tests, predictably it fails and I then implement the code in the Initialise method of the BalancePresenter and my test passes:

public void Initialise() 
{ 
    Balance balance = repository.GetCurrentBalance(); 
    balanceView.SetBalance(balance); 
}



0 comments: