Innovation in Practice?
Bob Walsh has pointed to a cool Guy Kawasaki Video about the 10 things (actually 11) you need to know about the Art of Innovation.
I was wondering if TypeMock was Innovative according to Guys Scale.
Well here goes:
1. Make Meaning not Money:
TypeMock was started to help teams get to speed with TDD, and create better software.
2. A 2/3 Word Mantra:
“Enabling TDD”
3. Jump to the next curb:
I am not sure about this. TypeMock might be just a better mocking system, although we do see it as jumping the curb as it uses new techniques like AOP and not just more/better APIs
4. Roll the DICEE, Deep, Intelligent, Complete, Elegant, Emotize:
Deep - Perhaps supporting Multi-Threads could be called deep.
Intelligent – Well we just got more intelligent (Perhaps one day TypeMock will write the mocks itself)
Complete – We are trying to give a complete solution. We have a Pre-Sales and Support Group although I know that we need more examples and training materials
Elegant – I think that NaturalMocks is.
Emotize – Hmm? Do you feel passionate about TypeMock?
5. Don’t Worry be Crappy:
The first version crashed when a struct was being mocked
6. Don’t be afraid to Polarize people:
Some people just hate TypeMock, Others swear by it.
7. Let 100 flowers blossom – expect the product being used in strange ways:
I don’t think this happened yet.
8. Churn Babe Churn:
I hopethat TypeMock is getting better all the time.
9. Niche Thyself:
Well I believe that we are in a Niche, But is TypeMock a Unique and High Value Product? Hmm
10. 10:20:30 You will have to listen to the Video for this.
I would really like to know what you think about
Generic Method Helpers
Per request of Paulo Morgado and others, we are implementing Generic API’s for TypeMock.
TypeMock has supported Generic since .NET 2.0 Beta has been out, but it did not use Generics in the API’s.
This is mainly to allow developers to use the same API’s for all .NET versions and to be able to upgrade their applications .NET version without problems.
We will add a new assembly with the Generic API’s. Here is what we are thinking of implementing:
// Create a Mock Mock m = Mock<TestedClass>.MockNextInstance(); // Mock all instances of a Type Mock m = Mock<TestedClass>.MockAll(); // Create a mocked instance MockObject<TestedClass> m = MockObject<TestedClass>.Create(); TestedClass t = m.Object; // Create a mocked instance for NaturalMocks TestedClass t = MockObject<TestedClass>.CreateObject();
Here are the API’s for generic Methods
// mock with Generic Method Mock m = Mock<GenMethodClass>.MockNextInstance(); m.AlwaysReturn("GenMethod", 11, Generic.Method<int>()); // run it GenMethodClass t = new GenMethodClass(); Assert.AreEqual(11, t.GenMethod<int>(1))
We will also be able to verify parameter types with
mock.ExpectCall("PassObject").Args(Check<IList>);
Any ideas from the community will be appreciated
Natural Mocks becoming more intelligent
Natural Mocks automatically mocks everything. This includes return values. So the following code:
using (RecordedExpecations recorder = RecorderManager.StartRecording()) { DummyClass.DoWork(); recorder.Return(new SqlInt32(1)); }
Won’t work as expected because SqlInt32 is being mocked.
This has bugged me a few times and I simply created the return value outside the recorder.
SqlInt32 mockValue = new SqlInt32(1)); using (RecordedExpecations recorder = RecorderManager.StartRecording()) { DummyClass.DoWork(); recorder.Return(mockValue); }
But this is not really nice, and a few customers have pointed out that this could be annoying!
So we are going to implement a feature that will know that you are creating a return value and will not mock it!
This way the first code will work as expected. Of course if you want to return a mocked value you will have to create the mock before, this might lead to non backward compatibility.
To those who want the first code to work as before (although I don’t think that anyone would), mock the return value before calling the recorded statements, and change the above code to:
using (RecordedExpecations recorder = RecorderManager.StartRecording()) { SqlInt32 mock = new SqlInt32(1); DummyClass.DoWork(); recorder.Return(mock); }
Of course if you are going to do that, you will have to define the behavior of the SqlInt32 and you might as well use ChainedMocks
using (RecordedExpecations recorder = RecorderManager.StartRecording()) { DummyClass.DoWork().Value; recorder.Return(1); }
What do you think about this feature?
IoC and Average Programmers
Travis Illig from Corillian has pointed me to a great post from Jeff Atwood - Your Code: OOP or POO?
Travis Wrote:
Jeff Atwood argues that over-architecture and strict adherence to strong object-orientation (exactly what has to happen in “design for testability”) doesn’t work well when you start considering who’s going to have to maintain this stuff once you move on to a different project
Rob Conery summarizes it well:
The ability to creatively think and solve without religious boundaries is what makes developing fun. The OO police are probably gonna pile on here Jeff but well done in speaking up and telling us “Neo” – phytes to “Free our mind”.
Opeth Commented:
Making something ridiculously complex for the sake of making it simple is like trying to put out a fire with gasoline.
Some programmers just need to take a deep breath and write code that is a delicious salami sandwich, and not an extravagantly prepared four course meal that tastes like shit.
I love that sentence.
This actually ties two post that Oren has been talking about lately: Test Driven Design vs. YAGNI and Great Code and Average Programmers.
Oren seems pretty pissed off and believes that a Company that will only code in a way that the average programmer would know – is Stupid. But hey, there might be some sense in what this company does. Take a look at the comment to Anders Norås blog Balancing maintainability, readability and testability.
Introducing this kind of abstraction throughout the code of a large app seems like a daunting task when there are several people that is going to write the code.
So are we going to be religiously coding toward OOP or are we going to Program fOr Others and as Jeff says:
consider the poor sap who will have to read and support this code after you’re done with it.
TypeMock is Freedom
Oren has answered my Quiz, by saying that
using(TextWriter writer = IoC.Resolve<IFileWriterFactory>().Create(filename)) writer.Write(text);
is easier to maintain! Well I cannot argue with that. Oren is one of a kind and I am sure that he can swallow these IoC containers and maintain them in his sleep. But would you have chosen this path if you didn’t need to test the code? Probably not.
We know that easy to understanding code makes the code maintainable, not only to developers who haven’t written the code but also the the developer who wrote the code 3 or more months beforehand.
but I think that using it [TypeMock] to enable brute force testing is harming the design process
Using TypeMock gives you Freedom. It gives you total freedom to choose your design:
- Freedom to choose When you want to design. Before/During or After writing implementation
- Freedom to choose How you want to create new objects. Using the new keyword/ a Singleton/ Factory or IoC Container
- Freedom to choose the Balance of your design. Flexibility/Extensibility/Maintainability/Cohesion/Just In Time Design (YAGNI)
You might be scared of this freedom, but it is not something new. We have always had this freedom until we had to nUnit test our code. Then we lost this freedom and had to find different constraining techniques. It might make our code better, but it might not. I personally like my freedom.
Design and Testability – YAGNI
After reading Roy’s Post and Oren’s Post who strongly side on Designing for testability I suddenly felt a De Ja Vu.
De Ja Vu
A few years ago, I was managing a project in a big company. One of the features that we where developing was a caching system. We needed the caching to boost performance on a multi location, multi server application.
We developed in a normal Waterfall methodology, and the architect (a really funny and talented guy) came up after a few weeks with his design.
The design was really well thought out and the cache was ready to support – multiple databases with many different kinds of databases along with other things. At the time we believed that we had to design the system with the future in mind.
The question did arise:
Do we need to support Multiple Database Instances?
The Answer was, No, Not really, but if we are going to support it later then the redesign will take us ages.
When I asked the team to read and tell me what they think about: “You Ain’t Gonna Need It“, everyone took this personally. The architect started to feel that his job has been taken away from him:
“I am getting paid to think about future problems” and the developers where also taken aback. They have all been trained to create flexible systems and not flexible processes.
I failed to convince them, and a couple of years later, the caching system became what I call “a black hole”. No one knew exactly how it works, and everyone was scared to change it, because it was soo complex. The developers now said: “We didn’t really need multiple database instance, we spent ages designing and developing this feature, and every bug we find, has to support this feature too, which just complicates matters, because no one uses it but we cannot remove it.”
Still when I talk to them about YAGNI, they all say: “But when we thought ahead and designing the <fill in whatever feature>, we saved weeks and could implement <another featrure> in days. It would have taken us weeks without it”.
I have to remind them that it took months to design, implement and test before we even needed it.
YAGNI, Low Coupling and Testability
So, what has this got to do with Oren and Roy’s posts.
Well, I am getting the same feeling from them that I got from my architect.
Oren, so you found that a “Couple of weeks after introducing the IFileWriterFactory” you found another use for it, and it saved you time.
Good for you!
But this is NOT YAGNI, the opposite. It sounds just like that <fill in whatever feature> that my team was so proud that it had managed to predict.
What about all the other features that have no use? The price of doing this everywhere can be quite expensive. Most of the time (apart from tests) – You Just Ain’t Gonna Need It.
There was a time when we had no choice, you had to either Design for Testability or not test at all. But in these times this is no longer true.
So, Does testing - driving your design, actually create the best design? I am not sure.
It does one thing for sure, It creates a low coupled (modular) design. But low coupling is NOT a silver bullet. A good design has to take and BALANCE many factors, this is a complex task. Adding Testability to these factors might unbalance your design.
Quiz: Which is easier to maintain:
File.WriteAllText(filename, text);
or
using(TextWriter writer = IoC.Resolve<IFileWriterFactory>().Create(filename)) writer.Write(text);
Recent Posts
- Product Status Peek – 2011
- Thanks Roy
- Typemock starts 2011 in a new location
- Agile Demos Smells
- I want loud disputes in our meetings
Categories
- .NET Tests
- Agile
- Code Integrity
- Community
- Debugging
- Fun
- Management for Geeks
- Marketing
- Product
- Release
- Reviews
- SharePoint
- TDD
- Time Management
- Uncategorized
- Unit Tests
Archives
- January 2011
- December 2010
- October 2010
- August 2010
- May 2010
- April 2010
- March 2010
- February 2010
- December 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- December 2008
- November 2008
- August 2008
- July 2008
- May 2008
- April 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- October 2006
- September 2006
