Need help with Unit Testing C# with Microsoft Fakes

sao123

Lifer
May 27, 2002
12,648
201
106
I have a class I am trying to write a unit test for, and I need to write a Shim to override the default constructor behavior, MS documentation suggests this is possible. but I can't seem to make it work.
This case has been simplified for the sake of brevity...Please help!

Code:
public class MyClass
{
[INDENT]private String MyString;
private String MyStringB;

public MyClass()
{
[INDENT]MyString = "MyString has been set in declaration.";
MyStringB = SetMyString();[/INDENT]
}

private String SetMyString()
{ return "My String has been set by the function call."; }[/INDENT]
}

1st unit test works perfectly.

Code:
[TestClass]
public MyTestClass
{
[INDENT]String DesiredOutCome = "My String has been set by the function call.";

[TestMethod]
public void TestMyClassConstructor()
{
   MyClass MyObject = new MyClass();
   PrivateObject obj = new PrivateObject(MyObject);
   var MyOutCome = obj.GetFieldOrProperty("MyStringB");
   Assert.AreEqual(MyOutCome, DesiredOutCome);
}[/INDENT]
}

Now I need one to remove the dependency through s Shim Injection, and this is the one that is failing.

Code:
[TestClass]
public MyTestClass
{
[INDENT]String NewDesiredOutCome = "MyString has been set to something different.";
[/INDENT]
[TestMethod]
public void TestMyClassConstructorWithShim()
{
   using (ShimsContext.Create())
   {
       MyNameSpace.Fakes.ShimMyClass.Constructor = (@this) =>
       {
           var shim = new ShimMyClass(@this)
           {
               SetMyString = () => { return "MyString has been set to something different."; }
           };
       };
       MyClass MyObject = new MyClass();
       PrivateObject obj = new PrivateObject(MyObject);
       var MyOutCome = obj.GetFieldOrProperty("MyStringB");
       Assert.AreEqual(MyOutCome, NewDesiredOutCome);
   };
}
}

Assert.Are equal failed. Expected <MyString has been set to something different.> Actual: <(Null)>

not sure why this is failing, im following all the examples I can find.

https://msdn.microsoft.com/en-us/library/hh549176.aspx
https://adamprescott.net/2012/08/21/a-shim-ple-tutorial-with-microsoft-fakes/
 

urvile

Golden Member
Aug 3, 2017
1,575
474
96
Why are you unit testing a constructor? Genuinely curious. It's not something I have ever seen unit tested. You aren't using a DI framework?

EDIT: you might want to take a look at Moq and the repository or adaptor pattern if you are using a database.
 
Last edited:

sao123

Lifer
May 27, 2002
12,648
201
106
i am trying to use a simplified example to mimic a real world situation I am dealing with without all the complex details. the plan is to unit test the methods of the class, however in its default constructor the calls a public API to get some data.

Unfortunately just instantiating an object of the class uses that constructor, so I need to DI that API call so the class methods can be isolated and tested.

Microsoft Fakes is what I was attempting to learn how to do the DI, by using the Shim to replace the API call functionality with a predetermined string I want it to return.
 

Merad

Platinum Member
May 31, 2010
2,586
19
81
i am trying to use a simplified example to mimic a real world situation I am dealing with without all the complex details. the plan is to unit test the methods of the class, however in its default constructor the calls a public API to get some data.

You're approaching the problem from the wrong direction. You need to push the API call behind an interface or abstract class, which you then pass into the constructor and whose behavior you can easily mock. If you use the common C# REST libraries that I'm familiar with (Refit, RestEase), this is a non-issue because those libraries are built around an interface representing the REST API methods you want to call.

Edit: You should probably also rethink your overall design here. IMO a constructor that does complex work (like an API call) is a big code smell. Also you'll typically want an API call to be async, which is not possible in a constructor.

I wouldn't use MS Fakes unless you have absolutely no choice. It locks you into a VS Enterprise license and, more importantly, locks you out of .NET Core (which it doesn't support). AFAIK it's more or less a dead library/tool since to my knowledge MS has no plans to migrate it to .NET Core.
 

sao123

Lifer
May 27, 2002
12,648
201
106
Considering this is a ASP.net Webforms app with several dozens of pages that i am trying to perform maintenance on, its not going to become .Net Core ever. The original developer didnt do ANY unit tests.
The enterprise license is not an issue because we already have it.

The MS shim testing framework is necessary because none of the other frameworks allow you to override private member behavior or unit test private methods.

I was attempting to do this incorrectly however, instead of trying to overwrite the code of the constructor at runtime with the shim context, i should just be overriding the behavior of the setmystring all the time. Bolded line was what I changed to make this work.

Code:
[TestMethod]
       public void TestMyClassConstructorWithShimReplaceCall()
       {
           using (ShimsContext.Create())
           {
               MyNameSpace.Fakes.ShimMyClass.AllInstances.SetMyString = (@this) => "MyStringB has been set to something different.";


               MyClass MyObject = new MyClass();
               PrivateObject obj = new PrivateObject(MyObject);
               var MyOutCome = obj.GetFieldOrProperty("_MyStringB");
               Assert.AreEqual(NewDesiredOutCome, MyOutCome );

           };
       }
 
Reactions: urvile
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |