CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

TypeMock isn't too powerful, and "Designing for Testability" is much more than merely mocking anyway

Roy has a post up today about TypeMock, testability, and DI.  The age old (ok, it just seems like we've been arguing over this for decades) question comes up again "is TypeMock too powerful?"  First, let's go pro-TypeMock because the attraction of TypeMock is pretty easy to understand.  I'm sick of fighting with C#'s static typing just to write unit tests with mock objects.  Pulling interfaces out just for unit testing is a bit tedious (ReSharper makes both creating the interfaces and bouncing around the code easy enough that that's not a real problem to me).  It is code noise that's there for no other reason than to make the compiler shut up.

The fear that TypeMock will "allow" people to write bad designs is partially bogus.  Part of the reason that I think TDD leads to better designs because it's painful to write tests for bad code (and by bad, I mean code with poor cohesion and poor separation of concerns).  TypeMock will deaden some "pain nerves" that detect bad design by making it possible and even efficient to unit test tightly coupled code (remember that coupling is important for other reasons besides "testability").  TypeMock usage could easily lead to less reusability and extensibility in the code that may turn out to be harmful in the end.  All the same though, I'm not too worried about people using TypeMock because TypeMock won't do all that much to help you test bad code.  Let me repeat that again.  TypeMock won't do all that much to help you test bad code.  Testability is more than just being able to mock interfaces.  Heck, coupling is quite a bit more than mere interfaces. 

If a caller has too much intimate knowledge about the innards of a dependency (tight coupling), setting up the mocking expectations on TypeMock is going to hurt and inform the experienced TDD'er that something is wrong with his or her design.  If a class or method is not cohesive, the test setup will still be too arduous for what you're trying to test (does the class do only one thing that's quick to test, or does the thing you want to test only happen in the middle of a bunch of other things).

So, to wrap up:  TypeMock does not end the idea of designing for with testability, and is not going to let you get away with a bad design anyway.
 

As an aside, Dependency Injection and Inversion of Control containers have far more usages than simply pushing in mock objects.  The existence of TypeMock doesn't even remotely eliminate the need or desire for DI/IoC tools (especially since I very rarely use the container in a unit test anyway).  Dynamic Languages might signal the upcoming death of the DI tooling, but TypeMock doesn't (if StructureMap becomes irrelevant, I just get to move on to new challenges).
 


 



Comments

Roy Osherove said:

I addressed DI as a concept, not the DI containers out that that do much more (such as interception AOP style and more). Perhaps the working should have been something like "is DI just for testability irrelevant?"

I fully agree that it can still be painful to write tests with typemock if your code under test is highly coupled, which is something I neglected to address.

But it does sound like you feel that TDD (or "naked TDD"?) is more about test driven design than anything else. Perhaps its time to find other ways to drive a better decoupled design than a test framework. It seems though that currently unit testing is as close we get to a self-design-review-in-realtime framework, which I think is not where we should be.

Roy

# January 18, 2008 8:44 PM

Jeremy D. Miller said:

@Roy,

I didn't disagree with anything *you* said, but you were linking to Jacob Profitt's ongoing "I really don't like DI" series.

"But it does sound like you feel that TDD (or "naked TDD"?) is more about test driven design than anything else."

I think the "if testing your code hurts, it's probably bad" is just a nice feedback loop.  I don't have any masochistic idea that "it should hurt!"  TDD is a design activity with a very helpful side effect of unit test coverage.  

# January 18, 2008 9:08 PM

Jeremy D. Miller said:

What I was trying to say is that I don't think TypeMock really changes TDD in any significant way.  

# January 18, 2008 9:09 PM

Colin Jack said:

"All the same though, I'm too worried about people using TypeMock because TypeMock won't do all that much to help you test bad code".

Sorry to be pedantic but I think you missed a "not", which could lead to confusion.

" Testability is more than just being able to mock interfaces.  Heck, coupling is quite a bit more than mere interfaces."

Amen to that.

"sick of fighting with C#'s static typing just to write unit tests with mock objects.  Pulling interfaces out just for unit testing is a bit tedious "

I agree. Some people in our team wanted to do interaction testing against our domain classes so we had two choices:

1) TypeMock - Design as we wanted to.

2) Rhino - Virtual methods and interfaces all over the domain.

The second option certainly wouldn't have improved the design so it was really a bit of a no brainer.

"So, to wrap up:  TypeMock does not end the idea of designing for with testability"

Having read (and in some cases re-read) some of the stuff at mockobjects.com I don't think many people use interaction testing in the way these guys originally intended. In addition much of the original documentation on tests driving design was written before interaction testing kicked off properly (unless my memory lets me down).

"I think the "if testing your code hurts, it's probably bad" is just a nice feedback loop.  I don't have any masochistic idea that "it should hurt!"  TDD is a design activity with a very helpful side effect of unit test coverage."

You are probably right, not enough has been written about this topic yet in my view as it is very interesting.

# January 19, 2008 2:54 PM

Jeremy D. Miller said:

@Colin,

I fixed that sentence.  Thanks for the catch.

Look at James Carr's list here:  blog.james-carr.org

# January 19, 2008 4:30 PM

Colin Jack said:

@Jeremy

Thanks that link was excellent, ta for posting it.

# January 20, 2008 4:59 AM

ISerializable - Roy Osherove's Blog said:

James Carr lists a nice bunch of TDD anti patterns . via Jeremy . Here's one example I run into often

# January 20, 2008 7:54 AM

ISerializable - Roy Osherove's Blog said:

I just wrote an email to someone regarding Typemock . We were discussing why they don't think Typemock

# January 20, 2008 5:59 PM

Christopher Bennage said:

The last two Octobers, I took a moment to reflect on the development tools I was using. It's interesting

# January 25, 2008 9:58 AM

Community Blogs said:

The last two Octobers, I took a moment to reflect on the development tools I was using. It's interesting

# January 25, 2008 10:31 AM

Steve Bohlen said:

I think its a mistake to insist on confabulating design-for-testability with 'I have to have interfaces for everything' as this post and others on similar topics tend to do.  Certainly declaring interfaces for everything just to support mocking does add needless 'noise' to a design, but explicit interface declaration is hardly the only way to ensure a class is mock-able even without typemock.

RhinoMocks (and a few other frameworks) support mocking of classes without the need for interfaces so long as the class' methods are declared virtual (or overridable in VB.NET-ese) -- I have used this technique for some time to enable mocking of classes that otherwise don't need an explicit interface defined for them in order to support the rest of the application's design.

Besides, unless you are either hyper-concerned about performance or are 100% sure that nobody will ever need to override one of your methods in a derived class, declaring non-virtual functions is tantamount to declaring the class as sealed: make REALLY sure this is a good idea before you consign some poor maintainer of your app to this23rd ring of hades.

Bottom line, I think, is that tools like typemock have their place alongside a bunch of other tools (that include sound app design principles) but that assuming that design-for-testability == explosion of otherwise unnecessary interfaces is a fallacy.

# February 1, 2008 11:18 AM

Jeremy D. Miller said:

@Steve,

"I think its a mistake to insist on confabulating design-for-testability with 'I have to have interfaces for everything' as this post and others on similar topics tend to do."

I *was* trying to make exactly that point in this post.

And in all seriousness, be very, very careful about mocking concrete objects with RhinoMocks.  That just doesn't isolate your tests enough because the concrete class behavior is in there just waiting to come out.

# February 1, 2008 11:45 AM

Eli Lopian’s Blog (TypeMock) » Blog Archive » Typemock and Design Issues said:

Pingback from  Eli Lopian’s Blog (TypeMock)  » Blog Archive   » Typemock and Design Issues

# February 6, 2008 6:56 PM

nblog said:

Od kilku miesięcy nic tu nie pisałem (oczywiście poza poprzednim nieplanowanym wpisem ). Jak łatwo się

# March 11, 2008 7:15 AM

Eli Lopian’s Blog (TypeMock) » Blog Archive » Mocking frameworks - dream feature said:

Pingback from  Eli Lopian’s Blog (TypeMock)  » Blog Archive   » Mocking frameworks - dream feature

# May 20, 2008 2:39 AM

TDD Anti Patterns | Developer Home said:

Pingback from  TDD Anti Patterns | Developer Home

# May 22, 2008 6:30 PM

The Case For Typemock | Developer Home said:

Pingback from  The Case For Typemock | Developer Home

# May 22, 2008 6:30 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeremy D. Miller

Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy previously worked as a systems architect building mission critical supply chain software for a Fortune 100 company and learned agile development practices as a .Net consultant at ThoughtWorks, one of the pioneers of agile development. Jeremy is the author of the open source StructureMap (http://structuremap.sourceforge.net) tool for Dependency Injection with .Net and the forthcoming StoryTeller (http://storyteller.tigris.org) tool for supercharged FIT testing in .Net. Jeremy's thoughts on just about everything software related can be found on his weblog "The Shade Tree Developer" at http://codebetter.com/blogs/jeremy.miller, part of the popular CodeBetter site. Jeremy is a Microsoft MVP for C#. Check out Devlicio.us!

Our Sponsors

Free Tech Publications

This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP