The easier way I think would be to use dependency injection. If your
classes take all their dependencies in their constructors, you can
easily pass real implementations, mocks, or stubs at test time. You
could use an IoC container to facilitate the runtime construction of
objects, and likewise you could use an automocking container at test
time, but you don't need to. I am a big fan of StructureMap and it's
AMC, you can see the usage here:
http://codebetter.com/blogs/jeremy.miller/archive/2008/02/09/automocker-in-structuremap-2-5.aspx
On Nov 25, 6:31 am, Dan Lash <[EMAIL PROTECTED]> wrote:
> I think the root of my problem is using a Service Locator pattern. I
> want my AMC to use stubs or mocks in different situations, but both
> tests are 'broken' because I'm using that particular IoC pattern. My
> code is asking the locator to give it an object that fulfills some
> interface -- and my test code is either going to want to put
> expectations on it OR not care about expectations but the object needs
> to work.
>
> So I guess an easier way to ask the question is: what is a good way to
> test interaction when using a service locator pattern?
>
> If the answer is AMC, how then can you control whether it's dolling
> out mocks or stubs? And if you can't how can you extract the mocks
> from your code to use in your test?
>
> Thanks alot,
>
> Dan Lash
>
> On Nov 24, 3:45 pm, Dan Lash <[EMAIL PROTECTED]> wrote:
>
> > 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
-~----------~----~----~----~------~----~------~--~---