Strict Mocks and Characterization Tests 18
This week I worked with a great group in Canada. This group of people had me using Moq for the first time and I found it to be a fine mocking tool. In fact, it reminded me of why I think the Java language is now far outclassed by C# and only getting more behind (luckily the JVM has many languages to offer).
One issue this group is struggling with is a legacy base with several services written with static API’s. These classes are somewhat large, unwieldy and would be much improved with some of the following refactorings:- Replace switch with polymorphism
- Replace type code with strategy/state
- Introduce Instance Delegator
- Use a combination of template method pattern + strategy and also strategy + composite
This is actually pretty standard stuff and this group understands the way forward. But what of their existing technical debt?
Today we picked one method in particular and attempted to work our way through it. This method was a classic legacy method (no unit tests). It also had a switch on type and then it also did one or more things based on a set of options. All of this was in one method.
If you read Fowler’s Refactoring Book, it mentions a combination of encapsulating the type code followed by replacing switch with polymorphism for the first problem in this method (the switch). We were able to skip encapsulating the type code since we wanted to keep the external API unchanged (legacy code).
So we first created a base strategy for the switch and then several empty derived classes, one for each of the enums. This is a safe legacy refactoring because it only involved adding new code.
Next, we created a factory to create the correct strategy based on the type code and added that to the existing method (we also added a few virtual methods). Again, a safe refactoring since it only involved adding effectively unused code (we did create the factory using nearly strict TDD). Finally, we delegated from the original method to the strategy returned from the factory. Safe again, since we had tested the factory.
So far, so good. But next, we wanted to push the method down to each of the subclasses and remove the parts of the logic that did not apply to each given type. We did a spike refactoring to see what that’d be like and it was at least a little dicey. We finally decided to get the original method under test so that as we refactored, we had the safety net necessary to refactor with confidence.
We started by simply calling the method with null’s and 0 values. We worked our way through the method, adding hand-rolled test doubles until we came across our first static class.
Their current system has DAO’s with fully static interfaces. This is something that is tough to fake (well we were not using and AOP framework, so …). Anyway, this is where we introduced the instance delegator. We:- Added an instance of the class as a static member (essentially creating a singleton).
- Added a property setter and getter (making it an overridable singleton).
- We then copied the body of the static method into an instance method, which we made virtual.
- We then delegated the static method to the virtual method.
- Then, in the unit test, we set the singleton to a hand-coded test double in the setup and reset the singleton in the tear down method.
We had to do this several times and on the third time (I think it was the third time), the hand-rolled test double would have had to implement several (17ish) methods and it became clear that we were ready to use a mocking framework. They are using Moq so we started using Moq to accomplish the remainder of the mocking.
After some time, we managed to get a test that essentially sent a tracer bullet through one path of the method we wanted to get under test. When the test turned green there was much rejoicing.
However, we had to ask the question: “So what are we testing?” After some discussion, we came up with a few things:- This method currently makes calls to the service layers and those calls depend on both an enumeration (replaced with a shallow and wide hierarchy of strategies) and options (to be replaced with a composition of strategies).
- It also changes some values in an underling domain object.
So that’s what we needed to characterize.
We had a discussion on this and as a group. We wanted a way to report on the actual method calls so we could then assert (or in Moq parlance Verify). We looked at using Moq’s callbacks, but it appears that those are registered on a per-method basis. We briefly toyed with the idea of using an AOP tool to introduce tracing, but that’s for another time (I’m thinking of looking into it out of curiosity) but we decided that we could instead do the following:- Begin as we already had, get through the method with a tracer.
- Determine the paths we want to get under test.
- For each path:
- Create a test using strict mocks (which fail as soon as an unexpected method is called)
- Use a Setup to document this call as expected – this is essentially one of the assertions for the characterization test.
- Continue until we have all the Setups required to get through the test.
- Add any final assertions based on state-based checks and call VerifyAll on the Moq-based mock object.
This would be a way we could work through the method and characterize it before we start refactoring it in earnest.
This might sound like a lot of work and it certainly is no cake walk, but all of this work was done by one of the attendees and as a group they certainly have the expertise to do this work. And in reality, it did not take too long. As they practice and get some of the preliminary work finished, this will be much easier.
Overall, it was a fun week. We:- Spent time on one project practicing TDD and refactoring to patterns (they implemented 5 of the GoF patterns).
- Spent time practicing some of Fowler’s refactorings and Feather’s legacy refactorings.
- Spent a day practicing TDD using mocks for everything but the unit under test. At the end they had a test class, one production class and several interfaces.
In retrospect, the work they did in the first three days was nearly exactly what they needed to practice for the final day of effort. When we started tackling their legacy code, they had already practiced everything they used in getting the method under test.
So overall great week with a fun group of guys in Canada.
I believe the saying goes: “How do you eat an Elephant?” “One bite at a time.” :)
i am fed up with tests
This would be a way we could work through the method and characterize it before we start refactoring it in earnest. Famous Quotes
It is my favorite patter name (not favorite pattern, just name).
People think that iphone 4 white is better iphone 4 black. Is that ture? Here you can judge by yourself.
very good paragraph.
internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.
The Design like the AJ 1 and AJ two, it apply the a visible air-sole unit designed by Tinker Hatfield. In addittion, Jordan Retro three is also the Jordan Loved ones for the very first time employing trapeze signs utilized to the Jordan Brand.
Most players, male or female, cringe at the thought of having to use a long iron. Most pull out a fairway wood over a long iron any day of the week. With a hybrid, you get the accuracy of an iron with the power of a wood. Depending on the length of time you’ve been playing, you might already be comfortable with your low irons. That’s perfectly acceptable, but beginners are often plagued with low iron difficulties, and a hybrid can eliminate many of these new-to-the-game mistakes.
Youth nfl jerseys available from the most popular sports brands at great prices. Thousands of teenager football fanatics would really love to get hold of their own NFL apparels.The only problem is the price of these goodies.
Whatever we believe about the benefits of this new technology, the likelihood is, as with all Prada inventions, that they will shortly become the norm for many a retailer, keen to make that added push towards comfort and availability for its shoppers. One thing’s for sure, shopping in the Prada bag sale will never be the same again.
This is really admired for the great services in this blog and using the great technology is visible in this blog. I am really satisfied by the great info is visible in this blog. I had really admired for the great services in this website that to using the great services in this blog Executive Director Job Description| General Manager Job Description| Consultant Job Description| Webmaster Job Description
When it comes to feather dress, what appears in your mind? Which kind brand of down jacket do you like prefer? Though there are many down jackets for you to choose from, on the word, which one you really enjoy? I want to say that canada goose coats is really your best choice. I believe you can’t agree with me any more. When you take the quality into consideration, you will find that it is superior to any other kind of coat. Besides, discount canada goose jackets is a world well-known brand, which has gained high reputation in the world, which has accepted by our customers and some organization. Because of its high quality, some of our loyal customers have promoted it to the people around them. In their opinion, it is good to informing others to know it. Recently, Canada Goose Trillium Parka is on hot sale. What I have to inform you is that all the products there are made by hand, so they are elaborative and elegant enough. It is really beautiful once you dress in. So, if you are a lovely girl or woman, go to the store to buy one for you. You will appreciate it that you have such a coat.In addition, they also have any other products like canada goose Gloves and canada goose jacket supplier.Hope your will like its!
Slewing bearing called slewing ring bearings, is a comprehensive load to bear a large bearing, can bear large axial, radial load and overturning moment.
Slewing bearing called slewing ring bearings, is a comprehensive load to bear a large bearing, can bear large axial, radial load and overturning moment.
http://www.spyderjackets-outlet.net
It is really a good example that most of the programmer should think about this. If we want to do much better for the code. I should understand it. right? You are very good at this and show us good coding idea.
Strict Mocks and Characterization Tests 16 good post8
Strict Mocks and Characterization Tests 17 hoo,good article!!I like the post!135