Code example related to this post are available at this GitHub repository.
Fakes framework contains two constructs which can be used to isolate code:
- Stubs – should be used to implement interfaces and stub the behavior of public methods.
- Shims – allow mocking the behavior of ANY method, including static and private methods inside .NET assemblies.
When using Stubs, you provide mocked implementation of any interface to the class or method which you are testing. This is done transparently before compilation and no changes are made to the code after the compilation. On the other hand Shims use the technic called IL weaving (injection of MSIL assembly at runtime). This way the code which should be executed is replaced at runtime by the code provided in the delegate.
The framework has caused some interesting discussions across the web. The pluralsight blog has found some negative points Rich Czyzewski describes how noninvasive tests can be create while using Fakes. And finally David Adsit nicely summarizes the benefits and the possible usage of the Fakes. From what has been said on the net, here is a simple summary of negative and positive points.
Pros
- Lightweight framework, since all the power of this framework is based only on generated code and delegates.
- Allows stubbing of any method (including private and static methods).
- No complicated syntax. Just set the expected behavior to the delegate and you are ready to go.
- Great tool when working with legacy code.
- The test are based od generated code. That is to say, a phase of code generation is necessary to create the “stubs”.
- No mocking is built-in into the framework. There is no built-in way to test whether a method has been called. This however can be achieved by manually adding specific code inside the stubbed method.
Migrating from Moles to Fakes
First a small warning, A bug was apparently introduced by the Code Contracts team, which causes a crash when building a solution which uses Fakes. You will need to install the latest version of Code Contracts. (If you do not know or use Code Contracts, you should not be impacted).If you have already used Moles before, you might be wondering, how much code changes will the migration need. To give you a simple idea, I have migrated the code from my previous post about Moles in order to use Fakes. Two major steps have to be taken during the migration:
- Change the structure of the project and generate new stubs
- Rewrite the unit tests to use newly generated classes
Following images show the difference between the old and new project structure (also note that I was using VS 2010 with Moles and I am now using VS 2012 with Fakes).
------------------> |
Rewriting code using Shims
Here is a classical example of testing a method which depends on DataTime.Now value. The first snippet is isolated using Moles and the second contains the same test using Fakes:[TestMethod] [HostType("Moles")] public void GetMessage() { MDateTime.NowGet = () => { return new DateTime(1, 1, 1); }; string result = Utils.GetMessage(); Assert.AreEqual(result, "Happy New Year!"); }
[TestMethod] public void GetMessage() { using (ShimsContext.Create()) { System.Fakes.ShimDateTime.NowGet = () => { return new DateTime(1, 1, 1); }; string result = Utils.GetMessage(); Assert.AreEqual(result, "Happy New Year!"); } }The main differences:
- Methods using Shims, do not need the HostType annotation previously needed by Moles.
- On the other hand a ShimsContext has to be created and later disposed when the stubbing is not needed any more. The using directive provides a nice way to dispose the context right after its usage and marks the code block in which the system has “stubbed” behavior.
- Only small changes are needed due to different names generated classes.
Rewriting code which is using only Stubs
Here the situation is even easier. Besides the changes in the naming of the generated classes, no additional changes are needed to migrate the solution. The following snippet test “MakeTransfer” method, which takes two accounts as parameters.
The service class containing the method needs Operations and Accounts repositories to be specified in the constructor. The behavior of these repositories is stubbed. This is might be typical business layer code of any CRUD application. First let’s see the example using Moles.
[TestMethod] public void TestMakeTransfer() { var operationsList = new List<Operation>(); SIOperationRepository opRepository = new SIOperationRepository(); opRepository.CreateOperationOperation = (x) => { operationsList.Add(x); }; SIAccountRepository acRepository = new SIAccountRepository(); acRepository.UpdateAccountAccount = (x) => { var acc1 = _accounts.SingleOrDefault(y => y.Id == x.Id); acc1.Operations = x.Operations; }; AccountService service = new AccountService(acRepository, opRepository); service.MakeTransfer(_accounts[1], _accounts[0], 200); Assert.AreEqual(_accounts[1].Balance, 200); Assert.AreEqual(_accounts[0].Balance, 100); Assert.AreEqual(operationsList.Count, 2); Assert.AreEqual(_accounts[1].Operations.Count, 2); Assert.AreEqual(_accounts[0].Operations.Count, 3); }
Note the way the repository methods are stubbed. Due to the fact that the stubs affect the globally defined variables (the list of operations, and the list of accounts) we can make assertions on these variables. This way we can achieve “mocking” and be sure that the CreateOperation method and the UpdateAccount method of Operation and Account repository have been executed. The operationsList variable in this example acts like a repository and we can easily Assert to see if the values have been changed in this list.
Let’s see the same example using Fakes:
[TestMethod] public void TestMakeTransfer() { var operationsList = new List<Operation>(); StubIOperationRepository opRepository = new StubIOperationRepository(); opRepository.CreateOperationOperation = (x) => { operationsList.Add(x); }; StubIAccountRepository acRepository = new StubIAccountRepository(); acRepository.UpdateAccountAccount = (x) => { var acc1 = _accounts.SingleOrDefault(y => y.Id == x.Id); acc1.Operations = x.Operations; }; AccountService service = new AccountService(acRepository, opRepository); service.MakeTransfer(_accounts[1], _accounts[0], 200); //the asserts here.... }
You can see, that the code is almost identical. The only difference is in the prefix given to the stubs (SIAccountRepository becomes StubIAccountRepository). I am almost wondering if MS could not just keep the old names, than we would just need to change the using directive…
Fakes & Pex
One of the advantages of Moles compared to other isolation frameworks, was the fact that it was supported by Pex. When Pex explores the code, it enters deep into any isolation framework which is used. Since Moles is based purely on delegates, Pex is able to dive into the delegates and generated tests according the content inside the delegates. When using another isolation framework, Pex will try to enter the isolation framework itself, and thus will not be able to generate valid tests.
So now, when Fakes are here as replacement of Moles, the question is whether we will be able to use Pex with Fakes? Right now it is not possible. Pex add-on for Visual Studio 11 does not (yet) exists and I have no idea whether it will ever exists.
I guess Pex & Moles were not that adopted by the community. On the other hand both were good tools and found their users. Personally I would be glad if MS continued the investment into Pex and automated unit testing though I will not necessarily use it everyday in my professional projects. On the other hand I would always consider it as an option when starting new project.
As far as I understood, moles will not be working with Visual Studio 2012 due to the existence of fakes. Also, fakes will not only be available only with the ultimate edition, it will also simply not work with the other editions (including tests already created with ultimate). So if companies already work with moles and make extensive use of it, they will only be able to migrate to fakes if all developers update to ultimate...
OdpovědětVymazatYes, you are right. I guess you could create a hack to get over that. Generated moles are just like any other .dll library. So having one Visual Studio 2010 to generate the moles should be enough and than everyone else with VS 2012 could use these :). But anyway - that is not a suitable solution.
VymazatI hope that MS will realize this and that tools such as Fakes & Pex will be available for anyone. MS is limiting their audiance and adoption, and that is not a good because these are valuable products.
Jan,
OdpovědětVymazatJust tried Visual Studio 2012 this weekend. I was humming along, porting a string similarity library from Java to C#, when I hit a road block porting my test cases. Having used Pex and Moles in 2010, I wanted to use it for string similarity testing as well.
Without all the facts, this seems like a step backwards. What trade-off am I missing? Is the fact that Pex can't test multi-threaded code the reason why Microsoft is moving away from Pex and Moles? Or is Pex going to be upgraded to support many more isolation frameworks, so that it is aware of TypeMock, RhinoMocks, Moq, Fakes, etc?
Hello John,
VymazatI completely agree, but I do not have more information than you. There is this information on the PEX official page:
"The Pex and Moles team will release an update of Pex for Visual Studio 2012 when the final release becomes available. Moles will not developed further so we recommend to migrate to Fakes."
Now the final release of VS is here, but no updates on PEX. Microsoft did just replace Moles with Fakes, but they are way to similar. But to me PEX actually was the interesting tool, I have used Moles only to be able to use PEX. I hope that they will not throw Pex away. If they release support for more isolation frameworks, I will not stay with Fakes. But once again, they don't make things clear...
Nice post very helpful
OdpovědětVymazatdbakings
Tento clanok mi usetril kopu bolesti, diky, palec hore
OdpovědětVymazatReally nice topics you had discussed above. I am much impressed. Thank you for providing this nice information here
OdpovědětVymazatSoftware Testing Company
Mobile Game Testing
Gameplay Testing
Switch Game Testing
Thanks for sharing the knowledge. That'll be applicable to data center migration tools
OdpovědětVymazatnice post..
OdpovědětVymazatSoftware Testing Training in Chennai | Certification | Online Courses
Software Testing Training in Chennai | Certification | Online Training Course | Software Testing Training in Bangalore | Certification | Online Training Course | Software Testing Training in Hyderabad | Certification | Online Training Course | Software Testing Training in Coimbatore | Certification | Online Training Course | Software Testing Training in Online | Certification | Online Training Course
Software Testing Training in Chennai | Certification | Online Courses
https://www.acte.in/software-testing-training-in-chennai
https://www.acte.in/software-testing-training-in-bangalore
https://www.acte.in/software-testing-training-in-hyderabad
https://www.acte.in/software-testing-training-in-coimbatore
https://www.acte.in/software-testing-training-course
Email - acteeducation@gmail.com
Phone - 9999138339
OdpovědětVymazatThank you for the nice article here. Really nice and keep update to explore more gaming tips and ideas.
Selenium Training in Chennai | Certification | Online Courses
selenium training in chennai
selenium training in chennai
selenium online training in chennai
selenium training in bangalore
selenium training in hyderabad
selenium training in coimbatore
selenium online training
Very good post, thank you. I am surprised to find your website
OdpovědětVymazatSEO Training in Pune
SEO Training in Mumbai
SEO Training in Delhi
SEO Training in Bangalore
SEO Training in Hyderabad
I am happy for sharing on this blog its awesome blog I really impressed. thanks for sharing. Youtube Mp3 Converter
OdpovědětVymazatI’m really happy with this informative blog, thank you so much for sharing this. Ogen Infosystem infosystem is a leading Web Designing and SEO Service provider in Delhi, India.
OdpovědětVymazatWebsite Designing Company in Delhi
The actual requirement for id verification service is higher right now. Trust Swiftly is truly the only platform that provides numerous verification methods, and a company can give far better security to their business by implementing all of the verification methods. If you take a look at this Trust Swiftly site, you will definitely get more and more knowledge about id verification service.
OdpovědětVymazatThanks for the cognitive information. Your content is the best in the internet so keep updating such content because we learn a lot from this.
OdpovědětVymazatWedding Venue in Meerut
Top 10 Schools in Meerut
Digital Marketing Expert in Meerut
Website Designing Company East Delhi
SEO Company in Hapur
SEO Company in Meerut
Non Availability of Birth Certificate Meerut
Website development in Meerut
still much uncertainty around what hybrid events will look like and the best practices for engaging hybrid audiences, but it's already clear that they offer new personalization opportunities. 10 things in common icebreaker and thank you for informing me about the interview
OdpovědětVymazatGreat Article.Thanks for the remarkable information. Please keep updating us.
OdpovědětVymazatIT Company in Meerut
Website Designing Company in Delhi
hoarding company
News in hindi
Magazine in india
“Best Digital Marketing Company in Meerut”.
OdpovědětVymazatTechdost Services Pvt Ltd is a recognized Software Development & Digital Marketing company situated in Meerut.
It offers a complete suite of IT and Marketing services to its clients.
Along with Meerut, it serves the cities of Delhi, Noida, Gurgaon, Dehradun, Ghaziabad, Saharanpur, and many more.
They are specialized in Web Development, Mobile App Development, SEO, PPC, Social Media Marketing, Content Writing, Graphic & Logo Designing, CRM & SRP Software Solutions, etc.
Techdost is a Google Certified Company founded by Mr. Shani Deshwal in 2017.
They have served 1800+ clients so far, with having 300+ ongoing projects.
The objective of the company is to provide the best Software & Marketing services to fulfill the needs, aim, and sole purpose of its clients.
Best Digital Marketing Company in Meerut
It changed into wondering if I may want to use this write-taking area regarding my supplementary website, notable thanks. Wifi Password Hacker Online
OdpovědětVymazatCertainly a great deal more education is needed. For me, this is extremely significant.
OdpovědětVymazatocean of games