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
Hello,

for tracing which mocks are called during a test I wanted to use the MockMethodCalledEventHandler mechanism.

Each mocked interface is initialized like this:

private void MockInterface(ref MockObject mock, Type type)
{
   mock= MockManager.MockObject(type);
   mock.Strict = true;
   mock.MockMethodCalled += new MockMethodCalledEventHandler(LogMockMethodCalled);
}

private void LogMockMethodCalled(object sender, MockMethodCallEventArgs e)
{
   string Message = string.Format("Method {0} mocked. Called from type {1}.",
                  e.CalledMethodName,
                  e.CalledType.FullName);
   Trace.WriteLine(Message);
}


No I would expect that every call to a mocked method would be traced.
But instead only the first call to a mocked object is traced. No more than one call to the event handler is made though I have more than one mocked class and more calls to each of them.

This is not documented like that and I find it a strange and unexpected behaviour.

If this method can not be changed to a more useful behaviour: Is there any other possibility to trace any called method in a typemock session?


Regards
Michael
asked by mknaup (8.5k points)

3 Answers

0 votes
Hi Michael,
I have tried this scenario and it works for me, there must be some other issue here. (Perhaps in the Trace Listener, you could try doing a Console.WriteLine)
Here is the code that I tried
[Test]
public void TestEvents()
{
   // Set trace output
   Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));

   // Make 3 IList Mocks and call Count twice for each
   MockObject mock1 = MockInterface(typeof(IList));
   mock1.ExpectGetAlways("Count",1);
   MockObject mock2 = MockInterface(typeof(IList));
   mock2.ExpectGetAlways("Count",1);
   MockObject mock3 = MockInterface(typeof(IList));
   mock3.ExpectGetAlways("Count",1);

   IList list1 = (IList)mock1.Object;
   IList list2 = (IList)mock2.Object;
   IList list3 = (IList)mock3.Object;

   int a = list1.Count;
   a=list1.Count;
   a=list2.Count;
   a=list2.Count;
   a=list3.Count;
   a=list3.Count;
}


private MockObject MockInterface(Type type)
{
   mock= MockManager.MockObject(type);
   // No need to make strict MockObjects are strict by default
   //mock.Strict = true;
   mock.MockMethodCalled += new MockMethodCalledEventHandler(LogMockMethodCalled);
}

private void LogMockMethodCalled(object sender, MockMethodCallEventArgs e)
{
   string Message = string.Format("Method {0} mocked. Called from type {1}.",
                  e.CalledMethodName,
                  e.CalledType.FullName);
   Trace.WriteLine(Message);
}

It prints:
Method get_Count mocked. Called from type MockIList.
Method get_Count mocked. Called from type MockIList.
Method get_Count mocked. Called from type MockIList.
Method get_Count mocked. Called from type MockIList.
Method get_Count mocked. Called from type MockIList.
Method get_Count mocked. Called from type MockIList.

Please tell me if the above code works for you
answered by scott (32k points)
0 votes
Thank you Scott for your quick and detailed answer.
As I see, your code works.
My code did not work because I created the mock once in the TestFixtureSetup and ran multiple tests as shown below.
Then only the first created instance seems to be mocked.

using System;
using System.Collections;
using System.Diagnostics;
using NUnit.Framework;
using TypeMock;

namespace XXX
{
   /// <summary>
   /// Summary description for TestUnexpectedCall.
   /// </summary>
   [TestFixture]
   public class TestUnexpectedCall
   {
      private MockObject testMock= null;

      public TestUnexpectedCall()
      {
         //
         // TODO: Add constructor logic here
         //
      }
      #region SetUp / Teardown

      /// <summary>
      /// Called before every executed test case
      /// </summary>
      [SetUp]
      public void SetUp()
      {
         // every test call will result in a "Count" getter call
         this.testMock.ExpectGet("Count", 1, 1);
      }

      /// <summary>
      /// Called after every executed test case
      /// </summary>
      [TearDown]
      public void Teardown()
      {
         MockManager.Verify();
         this.testMock.Clear();
      }

      [TestFixtureSetUp]
      public void TestFixtureSetUp()
      {
         MockManager.Init();

         MockInterface(ref this.testMock, typeof(IList));
      
      }


      /// <summary>
      /// Called after every executed test case
      /// </summary>
      [TestFixtureTearDown]
      public void TestFixtureTeardown()
      {
      }

      #endregion

      #region Test methods

      /// <summary>
      /// Checks IList
      /// </summary>
      [Test]
      public void MockTest1()
      {
         IList List = (IList)testMock.Object;
         int c = List.Count;
      }
      

      /// <summary>
      /// Checks IList
      /// </summary>
      [Test]
      public void MockTest2()
      {
         IList List = (IList)testMock.Object;
         int c = List.Count;
      }
      

      /// <summary>
      /// Checks IList
      /// </summary>
      [Test]
      public void MockTest3()
      {
         IList List = (IList)testMock.Object;
         int c = List.Count;
      }
      


      
      #endregion Test methods

   

      private void MockInterface(ref MockObject mock, Type type)
      {
         mock= MockManager.MockObject(type);
         mock.MockMethodCalled += new MockMethodCalledEventHandler(LogMockMethodCalled);
      }

      private void LogMockMethodCalled(object sender, MockMethodCallEventArgs e)
      {
         string Message = string.Format(">>>> Method {0} mocked. Called from type {1}.",
            e.CalledMethodName,
            e.CalledType.FullName);
         Trace.WriteLine(Message);
      }
   }
}


What is a "good" correction of this code:
Create a new mock in each SetUp or call ExpectAll ?

Thanks a lot in advance,

Michael
answered by mknaup (8.5k points)
0 votes
Hi Michael,
The 'bug' :evil: in the code is that MockManager.Verify() is called in the [TearDown] but the MockManager.Init() is in the [TestFixtureSetUp]. So after the first [TearDown] the MockManager is closed.

:idea: The rule is quite simple, MockManager.Init() and MockManager.Verify() must be done in the same scope.

So in your case, we will have to move the MockManager.Verify() to the [TestFixtureTearDown].
In the [TearDown] we will verify only the mocks that we created i.e. testMock.Verify()
Here is the code snippit:

[TearDown]
public void Teardown()
{
   testMock.Verify();
   // We don't really need to Clear the mock, It is done in the Verify()
   // this.testMock.Clear();
}
[TestFixtureTearDown]
public void TestFixtureTeardown()
{
   MockManager.Verify();
}


What is a "good" correction of this code:
Create a new mock in each SetUp or call ExpectAll ?
Creating a new mock in each SetUp is also a good idea, this will enable you to MockManager.Init in the [SetUp] but there are tests where it makes more sense to use the [TestFixtureSetUp]

Thank you Scott for your quick and detailed answer.

You are welcome.
answered by scott (32k points)
...