6

Within Visual Studio 2015 I have a test project to which I've added a fakes assembly.

In the unit test itself I create a shim for a static generic method that returns an instance to the generic type, such as:

using (ShimsContext.Create())
{
    ShimStaticClass.TheMethod<MyType>(() => instanceOfMyType);

    // ... code that uses StaticClass.TheMethod here ...
}

When the solution is built in debug mode the test runs fine and passes. However, when the solution is built in release mode the shimmed version of TheMethod does not get called, which is causing the test to fail.

I know that the shimmed method is not called because I've changed it to throw an exception by doing:

using (ShimsContext.Create())
{
    ShimForStaticClass.TheMethod<MyType>(() => 
    {
        throw new InvalidOperationException("Shim was called");
    });

    // ... code that uses StaticClass.TheMethod here ...
}

and this exception is not thrown.

I've turned on diagnostic logging and noisy verbosity for the fake but the build logs do not indicate any issues.

Chrisgh
  • 1,016
  • 2
  • 10
  • 18
  • 2
    Try turning optimizations off in release mode, rebuilding and rerunning the tests. It is possible that the compiler does not believe that the method needs to be called? – sQuir3l Dec 03 '15 at 17:39
  • So, turning off optimizations in release mode did not work for the test project (where the Fakes are referenced). It *did*, however, work when turning off the optimizations on the project that contained the code being tested. My presumption, now, is that the compiler is inlining the call to "StaticClass.TheMethod", given that the code is executing as expected when run using the release build. I don't think turning off optimizations is going to be a valid solution for this executable, however. – Chrisgh Dec 03 '15 at 22:48
  • 2
    It isn't a solution, but it may be a step in the right direction. You could maybe see why it thinks that the method invocation can be skipped and possibly there is an improvement in your code that can be done. – sQuir3l Dec 04 '15 at 04:55

1 Answers1

0

Did you try using the MethodImpl attribute and passing ImplOptions.NoInlining?

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
Randy
  • 2,270
  • 1
  • 15
  • 24
  • Unfortunately, the method being shimmed is in a 3rd party assembly. – Chrisgh Dec 09 '15 at 14:35
  • Did you try wrapping the method and using the above attribute? – Randy Dec 09 '15 at 14:57
  • I considered it, but did not try it. If that worked it wouldn't really be worth it in my case, as I'd be coding around this issue in an obtuse way, when I could code around it in a more straightforward way (at least in this codebase; obviously getting more implementation specific than my posted generic question.) – Chrisgh Dec 09 '15 at 15:08