Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling the original method from shim method

While creating shims for members of types in BCLs (or of any library for that matter). We often face a situation where we want to call the original method which we have overidden (be it inside the shim delegate or outside). E.G.:

System.Fakes.ShimDateTime.NowGet = () => DateTime.Now.AddDays(-1);

In the above code, all we want to do when the DateTime.Now is called is to return a day less than the actual date. Maybe this looks like a contrived example so other (more) realistic scenarios are

  1. To be able to capture and validate the argument values being passed to a particular method.
  2. To be able to count the number of times a particular method/property is accessed by the code under test.

I faced with the last scenario in a real application and couldn't find an answer for Fakes on SO. However, after digging into Fakes documentation, I have found the answer so posting it along with the question for the community.

like image 443
Varun K Avatar asked Feb 14 '23 10:02

Varun K


1 Answers

Fakes has a built in support for this; in fact there are two ways to achieve this.

1) Use ShimsContext.ExecuteWithoutShims() as a wrapper for the code you don't need shim behavior:

System.Fakes.ShimDateTime.NowGet = () => 
{
return ShimsContext.ExecuteWithoutShims(() => DateTime.Now.AddDays(-1));
};

2) Another approach is to set the shim to null, call the original method and restore the shim.

FakesDelegates.Func<DateTime> shim = null;
shim = () => 
{
System.Fakes.ShimDateTime.NowGet = null;
var value = ShimsContext.ExecuteWithoutShims(() => DateTime.Now.AddDays(-1));
System.Fakes.ShimDateTime.NowGet = shim;
return value;
};
System.Fakes.ShimDateTime.NowGet = shim;

Edit: Obviously the first approach is more concise and readable. SO I prefer it over explicitly declaring shim variable and removing/restoring the shim.

like image 127
Varun K Avatar answered Feb 24 '23 04:02

Varun K