I am working on a test project to prove out TDD/BDD before bringing it
to our next project. The test project is a simple 4-function
calculator and I've been able to get pretty far with state based
testing. Now I'm trying to do some interaction based testing and
running into some challenges.

The calculator is using a Service Locator pattern to get the
implementations of the interfaces. Because of this, I thought that the
Auto Mocking Container (or the idea of it) would fit perfectly. But I
have two different situations where I need the AMC to work
differently.

First, I am testing that when the Calculator is going to evaluate that
it interacts with the Math Engine properly. I have a test like this:

[Test]
public void should_use_math_engine_to_add()
{
    Expect.Call(_firstDigit.Digit).Return(4);
    Expect.Call(_addOperation.Operation).Return
(Calculator.Core.Operations.Add);
    Expect.Call(_secondDigit.Digit).Return(3);
    Expect.Call(_math.Add(4, 3)).Return(7);
    SetupResult.For(_addOperation2.Operation).Return
(Calculator.Core.Operations.Add);

    Mocks.ReplayAll();

    _calculator.PerformAction(_firstDigit);
    _calculator.PerformAction(_addOperation);
    _calculator.PerformAction(_secondDigit);
    _calculator.PerformAction(_addOperation2);

    Mocks.VerifyAll();
}

The problem I have is that the Calculator implementation uses the
Locator to get an IEnterNumber to append the IEnterDigits before
working with the Math Engine, and since I'm using an AMC it get's a
mock. Since a mock doesn't store properties like stubs do I'm getting
exceptions the mock can't return a value unless you specify it.

So one way I could fix that is by making my AMC return stubs instead.
That would allow the calculator to perform it's interaction with the
Math Engine and everything is good. I don't care how it uses
IEnterNumber internally, just that it interacts correctly with the
engine.

BUT I have a different test that would have the opposite problem if I
changed it. That test verifys the interaction between my Presentation
Model and my Core. This is how it's set up:

[Test]
public void should_perform_enter_digit_action_on_calculator()
{
    _digitAction.Digit = 2;
    _calculator.PerformAction(_digitAction);

    _digitAction.GetMockRepository().ReplayAll();

    _model.AddDigit("2");

    _digitAction.GetMockRepository().VerifyAll();
}

The way that this test works is it gets the IEnterDigit from the AMC
so it can set up the expectations on the same object that the Model
will use. This test relys on the AMC to give a mock to the Model so it
can have proper expectations set on it.


The main difference between the two is that in the first test I don't
care about the use of IEnterNumber because it's all internal -- but I
need it to work close to normal. The second test I care about
IEnterDigit because it's the method of communication between the Model
and the Core -- and I need to set expectations on it.

So after all that explanation my question is: am I doing this right?
If both of the tests and my testing strategy seem right, how can I
mock and/or stub properly in both of them when they are using a
Service Locator pattern?

I appreciate any advice on this.


Dan Lash

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Rhino.Mocks" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/RhinoMocks?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to