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
0 votes
Hi. I just downloaded Isolator. I've been using NMock for a little while, and I see there are some differences. I can't quite get the hang of telling one mock to return another mock when asked. Here's my code. The comment right after the using statement is the error I get in NUnit.

using System.Windows.Forms;
using NUnit.Framework;
using TypeMock;

//Strange.Class1.Test3 : TypeMock.TypeMockException : 
//*** Method Create in type Strange.Factory returns Strange.A and not TypeMock.Mock+a.

namespace Strange
{
   [TestFixture]
   public class Class1
   {
      [SetUp]
      public void SetUpMocker()
      {
         MockManager.Init();
      }
      [Test]  // We want to avoid running this test by using mock objects
      public void NonAutomaticTest()
      {
         ClassUnderTest cut = new ClassUnderTest();
         cut.MethodUnderTest();
      }
      [Test]
      public void Test3()
      {
         Mock sayer = MockManager.Mock(typeof(Sayer));
         Mock factory = MockManager.Mock(typeof(Factory));
         factory.ExpectAndReturn("Create", sayer.MockedInstance as A);
         sayer.ExpectCall("SayA");
         ClassUnderTest cut = new ClassUnderTest();
         cut.MethodUnderTest();
         MockManager.Verify();
      }
   }

   public class ClassUnderTest
   {
      public void MethodUnderTest()
      {
         Factory factory = new Factory();
         A a = factory.Create();
         a.SayA();
      }
   }

   public interface A
   {
      void SayA();
   }

   public class Sayer : A
   {
      public void SayA()
      {
         MessageBox.Show("A", "Message");
      }
   }

   public class Factory
   {
      public A Create()
      {
         return new Sayer();
      }
   }
}


Any help would be appreciated.
asked by wblum (640 points)

4 Answers

0 votes
Hi
The problem here seems to be that MockManager.Mock mocks the next creation of an instance (in other words next time you call new MyClass())
so when you call:
factory.ExpectAndReturn("Create", sayer.MockedInstance as A);

sayer.MockedInstance is null. It will have a value once you The Factory.Create method will create an instace of Sayer.

The solution is to create MockObject of sayer.
MockManger.MockObject method will create an instance and mock it so you
can use the instance as a return value or pass it as a parameter for a method.
Try this:
MockObject sayer = MockManager.MockObject(typeof (Sayer));
Mock factory = MockManager.Mock(typeof(Factory));

factory.ExpectAndReturn("Create", sayer.MockedInstance);
sayer.ExpectCall("SayA");
ClassUnderTest cut = new ClassUnderTest();
cut.MethodUnderTest();
MockManager.Verify();


:arrow: You can read this article for more in depth explenation about this issue.
answered by ohad (35.4k points)
0 votes
Ah, yes, that's the ticket. Thank you for pointing me to the blog post; it clarifies my understanding of Mock vs. MockObject nicely.
answered by wblum (640 points)
0 votes
Hi,

You can also use the more intuitive Natural Mocks. Note the differnce between a supplied, currently created object (mockSayer) and a future object (mockFactory).

      [TestMethod, VerifyMocks]
      public void NaturalMockTest()
      {
          using (RecordExpectations rec = RecorderManager.StartRecording())
          {
              A mockSayer = RecorderManager.CreateMockedObject<A>();
              Factory mockFactory = new Factory();
              rec.ExpectAndReturn(mockFactory.Create(), mockSayer);
              mockSayer.SayA();
          }
         ClassUnderTest cut = new ClassUnderTest(); 
         cut.MethodUnderTest(); 
      }
answered by gilz (14.5k points)
0 votes
It can be even simpler:

[TestMethod, VerifyMocks]
public void NaturalMockTest()
{
   using (RecordExpectations rec = RecorderManager.StartRecording())
   {
       Factory mockFactory = new Factory();
       mockFactory.Create().SayA();
   }
   ClassUnderTest cut = new ClassUnderTest();
   cut.MethodUnderTest();
} 
answered by eli (5.7k points)
...