Yevgeniy P
Yevgeniy P

Reputation: 1614

Microsoft Fakes shim constructor doesn't work

I m trying to shim a constructor in the following manner (as described in documentation):

using (ShimsContext.Create())
{
  ShimBehaviors.Current = ShimBehaviors.Fallthrough;
  System.Fakes.ShimUri.ConstructorString = (@this, s) =>
  {
    var shim = new ShimUri(@this)
    {
        AbsoluteUriGet = () => "http://test"
    };
  };

  var uri = new Uri("http://myhost:8100");
  Console.WriteLine(uri.Host);
}

(Note that I have chosen Uri only for the sake of example). The problem is that in the resulting Uri, none of the properties other than the shimmed AbsoluteUri, can be accessed. The last line above throws InvalidOperationException. In debugger I see that all properties other than AbsoluteUri are evaluated to throw InvalidOperationException.

In the above, I tried to add ShimBehaviors.Fallthrough in different ways using ShimBehaviors.Current or InstanceBehavior inside the shim, but nothing helps. In the debugger I also see that @this variable has all properties throw InvalidOperationException.

The behavior I expected to see is that my shimmed Uri would behave as normal other than returning different value for the property that I shimmed.

I tried the same with another system class, the same problem, except instead of InvalidOperationException it throws NullReferenceException.

Am I using it wrong?

Update:

it seems there is a workaround similar to the answer for this question. Basically, inside the shim constructor delegate, we can invoke a constructor on @this variable using reflection to reinitialize it the right way. Note that this needs to be done under ShimContext.ExecuteWithoutShims, otherwise it will go into infinite recursion.

I will still leave this question open, as I don't know why the shim constructor delegate always gets broken @this instance. Maybe it is a bug?

Upvotes: 0

Views: 100

Answers (0)

Related Questions