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 need to mix mocked and unmocked tests in one assembly. Unfortunately TypeMock does not see me to handle this well.

Take the code below, if you run the "Mocked" test on its own it works. Same for "Unmocked". However if I run the two together then the "Mocked" one fails.

Actually though this is not the full story:

1) If I run the tests using TMockRunner and NUnit (GUI or console) then the mocked one fails on the assertion.
2) If I use TestDriven.NET to run the tests from VS.NET then they pass
3) If I use TestDriven.NET to debug the tests from VS.NET then the mocked one fails

Is this expected behavior and if so why?

I am using the latest version of TypeMock.

Thanks,

Colin



using System;
using NUnit.Core;
using NUnit.Framework;
using TypeMock;

namespace ErrorWithMocking
{
[TestFixture]
public class Tests
{
[Test]
public void UnMocked()
{
ToTest toTest = new ToTest();

Assert.IsFalse(toTest.Mocked, "The class should not be mocked");
}

[Test]
public void Mocked()
{
MockManager.Init();

Mock mockForToTest = MockManager.MockAll(typeof(ToTest), Constructor.NotMocked);

mockForToTest.ExpectGetAlways("Mocked", true);

ToTest toTest = new ToTest();

Assert.IsTrue(toTest.Mocked, "The class is not mocked");
}
}

internal class ToTest
{
internal bool Mocked
{
get
{
return false;
}
}
}
}
asked by colinjack (1.2k points)

5 Answers

0 votes
Hi Colin,

The answer here is quite simple. :-)
You must make sure MockManager.Verify is called after the mocked test. ([TearDown] is a good place, as it will be called even if the test fails).

TypeMock.NET doesn't know when a test begins or ends.
In your case you told TypeMock to mock all future instances of ToTest (MockManager.MockAll)
And to mock it Always! (ExpectGetAlways) and not only once .

Now if the first test runs first - the tests will pass.
But it the second test runs first, ToTest will still be mocked.
As the order of the test is different is each tool (you can check it) you get the results that you saw

BTW, thanks for the example
answered by scott (32k points)
0 votes
Hi Scott,

First off thanks for the speedy reply, I've only made a few posts on the forum but all of them have been replied to quickly.

Anyway I'm not sure that not calling Verify explains what I'm getting. If the class was already mocked then this line would cause a TypeMockException to be thrown:

Mock mockForToTest = MockManager.MockAll(typeof(ToTest), Constructor.NotMocked);


What I'm seeing does not seem to be that ToTest class is already mocked when Mocked runs, its actually that I'm failing to mock the class at all.

To try and show this I've added the Verify call (I forgot to put it in my example) and an Assert that verifies that the class has not already run to try and prove that this is the case.

Also the Unmocked test does run first in this case, to prove this I've added a Debug.WriteLine to each test. The output you get is:

------ Test started: Assembly: TypemockTest.dll ------

Unmocked
Mocked
TestCase 'ErrorWithMocking.Tests.Mocked' failed: The class is not mocked
   d:documents and settingsdevmy documentsisual studio projectsserviceschapter1	ypemocktestclass1.cs(43,0): at ErrorWithMocking.Tests.Mocked()


1 succeeded, 1 failed, 0 skipped, took 0.19 seconds.



---------------------- Done ----------------------


I may be being dumb here but I can't see why the mocking is failing.





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

namespace ErrorWithMocking 
{ 
   [TestFixture] 
   public class Tests 
   { 
      [TearDown]
      public void TearDown()
      {
         MockManager.Verify();   
      }

      [Test] 
      public void UnMocked() 
      { 
         Debug.WriteLine("Unmocked");

         ToTest toTest = new ToTest(); 

         Assert.IsFalse(toTest.Mocked, "The class should not be mocked"); 
      } 

      [Test] 
      public void Mocked() 
      { 
         Debug.WriteLine("Mocked");

         MockManager.Init(); 

         Assert.IsFalse(MockManager.IsTypeMockedAll(typeof(ToTest)));

         Mock mockForToTest = MockManager.MockAll(typeof(ToTest), Constructor.NotMocked); 

         mockForToTest.ExpectGetAlways("Mocked", true); 

         ToTest toTest = new ToTest(); 

         Assert.IsTrue(toTest.Mocked, "The class is not mocked"); 
      } 
   } 

   internal class ToTest 
   { 
      internal bool Mocked 
      { 
         get 
         { 
            return false; 
         } 
      } 
   } 
}
answered by colinjack (1.2k points)
0 votes
Ok.
Now just add MockManager.Init() in the [SetUp] and your done.

The reason for this behavior is that TypeMock.NET doesn't start mocking until the first time Init() is called. If a type was called before Init() it won't be mocked. For more information see the documentation about InitFastMode()
answered by scott (32k points)
0 votes
Ahhhh...I never realised that :D

Might be worth specifying that in the the documentation for Init(), though now I think about it I guess it makes sense because I guess once the method is JIT compiled you've lost your chance?

Now I have to work out how to ensure that MockManager.Init is called before any tests (even unmocked ones) run...or alternatively chicken out and move my TypeMock unit tests to a different assembly.

Anyway thanks for your help.
answered by colinjack (1.2k points)
0 votes
Happy to help.
Good luck with working out what works best for you.
In any case calling MockManager.Init() shouldn't harm unmocked tests.
answered by scott (32k points)
...