chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
Hi,

I'm having a problem when trying to use MockAll from the reflection mocks in conjunction with some natural mocks.

Basically, I want to mock out all calls to two different functions in the same class. I want to do this in the test fixture. This all works fine using MockAll.

The problem comes when I want to override one of the mocked functions using natural mocks. The function itself gets overriden correctly (i.e. it returns the return value I specify in the natural mocks section), but it seems that the mock all for the other functions in the class doesn't work anymore.

e.g.

Mock mock = MockManager.MockAll<Foo>();
mock.AlwaysReturn("Bar1", 1);
mock.AlwaysReturn("Bar2", 2);

...

Foo foo = new Foo();

using (RecordExpectations recorder = RecorderManager.StartRecording())
{
    recorder.ExpectAndReturn(foo.Bar1(), 5);
}

foo.Bar1();  // this is the natural mocked version, returning 5
foo.Bar2();  // this is the original version, not the AlwaysReturn version


Looking at the trace, I see the original mock all calls for both Bar1 and Bar2 functions, but for some reason, the original version of Bar2 gets called. If I take out the natural mocks section, then both Bar1 and Bar2 have the return values specified by the MockAll object (as expected).

Is this a bug, or a known limitation?

Thanks,

Rory
________
Honda Racing Corporation
asked by rorydriscoll (3.8k points)

2 Answers

0 votes
Hi,

Actually its more of a known limitation kind of thing.
Try to think of MockAll as kind of a default on the instance level.
i.e. if you dont create other mocks, all calls will be reverted to the expectation done on the mockall instance.

When you record the natural call after you created the real instance a new mock is created behind the scenses to store the new expectation and that mock override the calls to that mockall instance.

In short you will will need to re-record the rest of the expectation for the new instance.

Thats being said, I think that what you raise here is impoortant and I'll discuss it here and see what people think.

last thing, do take a look in our block mechanism (see my other post). I think that it will really help you.one.
answered by lior (13.2k points)
0 votes
Thanks for the feedback. What I've done for now is to copy the specific functions I want to stub out by default to the particular instance mock which roughly achieves what I'm looking for.

I should probably explain a little better what I am trying to achieve: I wrote a C++ mocking framework which basically allows you to specify default return values for any function. If you specifically record one of the default function calls, then that recorded version takes priority. After about 6 months of using both TypeMock, and the C++ framework, we began to notice that the C++ tests were far easier to read, debug and maintain. It turns out that the reason for this is the default stubs, and being able to override them.

In C#, we may have a test like this:

      [Test]
      [VerifyMocks]
      public void TestMyFunctionDamagesBarIfCalculateSomethingElseIsPositive()
      {
         Bar bar = new Bar();

         using (RecordExpectations recorder = RecorderManager.StartRecording())
         {
            recorder.DefaultBehavior.CheckArguments();

            recorder.ExpectAndReturn(bar.Property1, 5);
            recorder.ExpectAndReturn(bar.Property2, 6);
            recorder.ExpectAndReturn(bar.Property3, 7);
            recorder.ExpectAndReturn(bar.Property4, 8);

            bar.CalculateSomething(5, 6, 7);
            recorder.CheckArguments();
            recorder.Return(123);

            bar.CalculateSomethingElse(123, 8);
            recorder.CheckArguments();
            recorder.Return(5);

            bar.Damage();
         }

         Foo foo = new Foo();
         foo.MyFunction(bar);
      }


      [Test]
      [VerifyMocks]
      public void TestMyFunctionKillsBarIfCalculateSomethingElseIsNegative()
      {
         Bar bar = new Bar();

         using (RecordExpectations recorder = RecorderManager.StartRecording())
         {
            recorder.DefaultBehavior.CheckArguments();

            recorder.ExpectAndReturn(bar.Property1, 5);
            recorder.ExpectAndReturn(bar.Property2, 6);
            recorder.ExpectAndReturn(bar.Property3, 7);
            recorder.ExpectAndReturn(bar.Property4, 8);

            bar.CalculateSomething(5, 6, 7);
            recorder.Return(123);

            bar.CalculateSomethingElse(123, 8);
            recorder.Return(-5);

            bar.Kill();
         }

         Foo foo = new Foo();
         foo.MyFunction(bar);
      }


In, C++ the tests end up looking more like this:
   // REGISTER_STUB(Function, optional ReturnValue)
   // EXPECT_RETURN(FunctionCall, ReturnValue);

   FIXTURE(...)
   {
      REGISTER_STUB(Bar::GetProperty1, 5);
      REGISTER_STUB(Bar::GetProperty2, 6);
      REGISTER_STUB(Bar::GetProperty3, 7);
      REGISTER_STUB(Bar::GetProperty4, 8);
      REGISTER_STUB(Bar::CalculateSomething, 1);
      REGISTER_STUB(Bar::CalculateSomethingElse, 1);
      REGISTER_STUB(Bar::Damage);
      REGISTER_STUB(Bar::Kill);
   }

   TEST_FIXTURE (MyFunctionUsesResultOfFirstCalculationInSecondCalculation)
   {
      Bar bar;

      RECORD
      {
         EXPECT_RETURN(bar.CalculateSomething(5, 6, 7), 123);
         EXPECT_RETURN(bar.CalculateSomethingElse(123, 8), 5);
      }

      Foo foo;
      foo.MyFunction(bar);
   }

   TEST_FIXTURE (MyFunctionDamagesBarIfFinalCalculationIsPositive)
   {
      Bar bar;

      RECORD
      {
         EXPECT_RETURN(bar.CalculateSomethingElse(0, 0), 1).IgnoreArguments();
         bar.Damage();
      }

      Foo foo;
      foo.MyFunction(bar);
   }
   
   TEST_FIXTURE (MyFunctionKillsBarIfFinalCalculationIsNegative)
   {
      Bar bar;

      RECORD
      {
         EXPECT_RETURN(bar.CalculateSomethingElse(0, 0), -1).IgnoreArguments;
         bar.Kill();
      }

      Foo foo;
      foo.MyFunction(bar);
   }


This is a very trivial example, but I hope my point about the tests being more explicit is clear enough. If I'm testing some conditional behaviour at the end of a function, and I've already tested the code up until that point, then I don't need to test it again. More than that, what I am testing becomes much clearer when I don't have the clutter of setting the expectations on the code I don't care about.

In the example above, I don't need to actually test that I call PropertyN/GetPropertyN() since I am using the results in CalculateSomething() and CalculateSomethingElse(), which I am testing. In the last two tests, the result of CalculateSomething() is irrelevant, but I'm still forced to set an expectation using TypeMock (assuming that running the real code will do something nasty).

Although we try and keep our functions as small as possible, we still end up needing a lot of test code for some of our tests. When that test goes wrong, it becomes really hard to work out which code is relevant to the test, and which is just there to make sure the test can actually run ok.

Anyway, thanks again for the help on this one. I'd lo
answered by rorydriscoll (3.8k points)
...