0

I need to run an integration/regression test suite for our application and the application is supposed to behave differently at different times of the day. I cannot change the system time since other apps depend on it I would like to mock DateTime.Now for this purpose. However, when I put the mocking in the main method, exceptions were thrown. When I use mocking in an nunit test for the same application, it works fine. Can typemock be used only in the context of a unit test? Is there anyway I can run the solution with mocking enabled? I ran the solution through TMockRunner.exe as well but had the same issue.

Thanks!

I see this error when I run using the method that Travis mentioned @Travis Illig, The code for the wrapper is:

 class Program
  {
    static void Main(string[] args)
    {
      ExpectationsSetup();

      ConsoleApplication2.Program.Main(args);
    }

    public static void ExpectationsSetup()
    {
      Isolate.WhenCalled(() => DateTime.Now).WillReturn(new DateTime(2010, 1, 2));
    }
  }
I see the following error:

Unhandled Exception: TypeMock.TypeMockException:
*** No method calls found in recording block. Please check:
 * Are you trying to fake a field instead of a property?
 * Are you are trying to fake an unsupported mscorlib type? See supported types
here: http://www.typemock.com/mscorlib-types
   at gt.a(c0 A_0, Boolean A_1)
   at bg.a(Boolean A_0)
   at dt.b(Boolean A_0)
   at i2.b(Boolean A_0)
   at i2.a(Object A_0, Boolean A_1, Func`1 A_2, Action A_3, Action A_4, Action A
_5, Boolean A_6)
   at i2.b(Object A_0)
   at TypeMock.ArrangeActAssert.ExpectationEngine`1.a(TResult A_0)
   at ConsoleApplication2Mock.Program.ExpectationsSetup() in C:\Users\shvenkat\D
ocuments\Visual Studio 2010\Projects\ConsoleApplication2\ConsoleApplication2Mock
\Program.cs:line 22
   at ConsoleApplication2Mock.Program.Main(String[] args) in C:\Users\shvenkat\D
ocuments\Visual Studio 2010\Projects\ConsoleApplication2\ConsoleApplication2Mock
\Program.cs:line 14

Any help will be appreciated Thanks!

1 Answers1

0

The typical use of Typemock Isolator is within the context of a unit test or a small testing environment. There is a non-zero level of overhead associated with running Isolator (or any other profiler-based product like NCover) in a process, so you generally don't want to do that.

However, there are some total edge-cases when you really do want to run Isolator on a regular process, and that is possible.

Here's an article I wrote from a while back explaining how you can do this to a Windows Service, for example.

The basic algorithm holds:

  • Enable Typemock Isolator (either by setting up the profiling flags on the process or by running things through TMockRunner.exe).
  • Set up your expectations (this is where you mock DateTime.Now or whatever else you want mocked out).
  • Let the application finish starting up and run as normal.

The first step is easy enough - it's just like if you were running it in a unit test environment. It's the second step that can be difficult. It means you need to have some sort of "wrapper" or something that runs before the rest of your application is allowed to start that will set up your expectations. This normally happens in a test setup method or in the "arrange" part of your "arrange-act-assert" unit test. You'll see an example of this in my article.

Again, I'll warn you about performance. It's probably fine to do something like this in a test environment like you mention you're doing, but I don't think I'd do it in production.


A specific note about your program and the error you're seeing:

I tried to set up a reproduction of it and while I was able to mock other things, I wasn't able to get DateTime.Now mocking to work either. I got the same exception you're seeing.

For example, try this in your wrapper:

class Program
{
  static void Main(string[] args)
  {
    ExpectationsSetup();

    ConsoleApplication2.Program.Main(args);
  }

  public static void ExpectationsSetup()
  {
    // Mock something OTHER than DateTime.Now - this mocks
    // the call to your wrapped application.
    Isolate
      .WhenCalled(() => ConsoleApplication2.Program.Main(null))
      .DoInstead(ctx => Console.WriteLine("faked!"));
  }
}

Running that wrapper through TMockRunner.exe, you'll actually get the mocking to work. However, switching it back to DateTime.Now, you'll get the exception again.

I did verify that mocking DateTime.Now in a unit test environment does work. So there must be something special about the unit test environment, though I don't know what.

Figuring out that difference is a little more in-depth than something that can be handled here. You should contact Typemock support with this one and explain the situation. They are pretty good about helping out. Be sure to send them a reproduction (e.g., a simple console app showing the issue) and you'll get a faster/better response.

Travis Illig
  • 23,195
  • 2
  • 62
  • 85
  • Thanks Travis! I used something similar. Mine is a console application and I wrote a wrapper console application which does the expectation setup etc class Program { static void Main(string[] args) { ExpectationsSetup(); ConsoleApplication2.Program.Main(args); } public static void ExpectationsSetup() { Isolate.WhenCalled(() => DateTime.Now).WillReturn(new DateTime(2010, 1, 2)); } }. It throws exceptions when I run through TMockRunner though.. – user1532105 Jul 24 '12 at 20:54
  • You should probably update your question to include the exception information and your wrapper console app. Sort of hard to troubleshoot or offer advice without all the info. – Travis Illig Jul 24 '12 at 22:00