Unit Testing, Agile Development, Leadership & .NET - By Roy Osherove
Ignoring the pros/cons of each, the fact is that there is a lot of code out there that isn't written with "Forced Design" in mind. As an independent consulting, the reality is that I will probably have to work with that code some day, regardless of what I think. It is not feasible to rewrite this working code just to make it testable. I appreciate the fact that TypeMock helps me in those cases. Sadly, a lot of companies balk when they are asked to spend extra for a mocking tool, and I can't use TypeMock.
You're asking, so my answer is "Yes, TypeMock should have some sort of free version of Isolator".
Yup, I used to use Isolator when it had a "community" version, but had to migrate to Rhino when that version has been dropped. When working at some of my clients, it was already hard enough to make them understand why I was adding an external framework for mocking, let alone telling them they had to pay for one.
Can you give an example of some code you would like to write, because it is the best API, that would be discarded because it isn't testable without TypeMock?
You offer up a number of straw man arguments. Are you intentionally misrepresenting TypeMock detractors, or do you really not understand what makes use of statics, etc "bad design" (and no, testability is not the answer)?
I agree about concrete limitation in the specific tool. I've seen design decisions based on that MSTest did not have rowtest.
But I don't see that design decisions driven by mocking frameworks is worse than other TDD heuristics indicating a design smell. You could also say that "if you need your tests to drive the design, you are doing it wrong", which in principle may be true, but I don't see it as a problem.
I disagree with the notion that TypeMock usage is an indication of bad design or bad TDD overall, but it is a power vs responsibility situation. If you don't have any mental red flags that go off when you veer off into crazy tangents, you can dig yourself in waaay deep with something as powerful as TypeMock.
"Just because you can, doesn't mean you should", springs to mind.
It is regrettable, however, that the syntactic differences, test code dependency and versioning+deployment of redist assemblies makes the choice of mocking+testing framework a somewhat committing decision at a way too early stage of the component lifetime.
Joshua, you are barking up the wrong tree. whether or not I agree with statics is not the issue. it's that I let a tool decide for me if statics are good or bad - that's the issue.
At this stage in our development (think personal rather than project) and with us being a small software team I actually feel that using the free tools helps us maintain good design patterns when using TDD (while under increasing time pressures - as is always the case).
The crucial need for Typemock in my opinion is getting legacy code under test - so that it can be moved towards a design that more fits with what works with the free tools.
So for me the smart move for Typemock and for acceptance within the community is for there to be a free version that exactly mirrors the ability of the free solutions and you can upgrade quickly if needed.
With that model adoption rates would rise and it would be a much easier upgrade if required. Upgrading to a paid solution has many stumbling blocks:
- Time to learn the new syntax,
- Time to configure (or finding out if configuration is required at all),
- Time to work out are there any different versions available (if so what are the trade offs),
- Are there multiple methods for doing the same thing (if so taking the time to standardise the approach across the company and making sure that the standardised approach is the best from the start),
- ... and more which boils down to 'an unknown amount of time to implement with unknown results'.
- And as the thing that keeps this a boolean choice it costs money to move forward with Typemock (so the above 'problems' are magnified out of proposition to moving to an alternative free solution).
To me that means we will never convert, because its a big all or nothing effort, whereas if there was a community version IMO Typemock would be more valuable than other solutions as there is an upgrade path available should you ever require it... so the reasoning becomes:
- We know how to use it already and all our outstanding questions have been answered through daily use and being part of the Typemock community, and we did this all while it was free and we could easily throw it away if it didn't suit.
- It costs money but now we can estimate effectively that with this legacy application we want to get under test will take X more man hours with the community version meaning that if the Typemock upgrade costs less than the X more man hours then the decision is really easy for this project and actually means we have it for future projects (if needed) too.
For me it boils down to the point where I have to weight things up and decide 'will using the full version of Typemock save us money'? The more you make that an easy, stress free decision the better and right now I'm not considering Typemock but I would definitely be interested in a community version that did everything (for example) MOQ does - we would use it for the next project because if it works out well it gives us more options with no down side.
hey roy this is interesting question, to me Well-designed objects should be context independent and not tied to its environment; objects tightly coupled to its environment will be difficult/impossible to use in another context, which will always be highlighted in a unit test. Sure by using typemock's magic, for a unit test you can break the objects dependency on it environment, there is not wrong with this if we are using the same tecnhiques in production code. The main issue is I would not use profiler API in production code, using this in test code, simply silencing all the feedback my tests are giving me about the design of the object under test. The real issue is would you use different underlying techniques in the context of a test and production code ? For me the answer is no and thats why i would tend not to use the feautre in typemock that relied on the .NET Api profiler stuff
Do you consider patterns such as dependacy inversion a code smell? Besides the fact that Moq forces me to break up my dependancies and introduce a lot of interfaces, I generally like the idea of following rigid design patterns.
I tend to view the unit test as a client of the code under test. And, in my opinion, that client is as important as the application. Furthermore, am I really letting the tool's limitation (moq) drive my design? In reality, isn't it the platfom and the language that are imposing those changes? Any bit of flexibility that I put in my design (to serve the unit tests) might be useful one day, who knows? I tend to draw the line when those changes also introduce a level of complexity in the production code that I'm not comfortable with. Anyway, as an architect, I'm the one making the decisions.
Roy, you make a good argument and its one I have considered myself. That being said, I'm generally of the "don't bother with Typemock" persuasion simply because I have not been able to think of a design pattern where my application would have been made more supple and loosely coupled by using language features that are prohibited by traditional mocking.
Of course there are always edge cases that come up, maybe once a project an odd problem presents itself. Though in these cases it is usually an indicator of something that I overlooked that needs refactoring.
So what's the sales-pitch? Can you give me an example of a pattern that I might actually WANT to apply in my application that the other tools can't handle?
By all means let us have a trimmed down free version.
The whole wave of cool IOC-everywhere design is starting to wear on me - IOC is a fine pattern in some cases - not all. Besides you're not going to be refactoing everything to make it shiny and IOC'y when consulting on legacy systems.
I've seen your talks for 3 consecutive years in Florida, Barcelona and Berlin - I really appreciate the pragmatic approach to software development and testing that you advocate and I hope that more of the "purists" can be turned to the pragmatic side.
Shame about the guitar - I was looking forward to a new song :-)
First, I agree that TypeMock is a totally good thing - it tests code that you didn't write (legacy), code you have no control over (e.g. DateTime.Now), and 3rd party code that wasn't designed with testing in mind (e.g. a shell extension driver). Rhino, Moq, and others can't do this.
Regarding a free version of Isolator, I think it's a great idea. Personally, the idea of a $800/developer seems pretty steep. I was hoping for 200 range for small companies like mine.
Regarding a free version,
Isolator is two things: the core, which makes all the magic, and the isolation framework, which uses this magic. Several other tools (CThru, SilverUnit, Ivonna, perhaps Racer) use the core and don't need the isolation part. So, following the SRP, it makes sense to put the core into a separate product and give it for free or for a symbolic price, while the Isolator and other tools would work on top of it. So, whenever I just need an AOP engine, I don't have to pay for a full-blown framework with three APIs supporting two languages, I just get the core.
It is also possible that I build my own framework on top of that core, and this framework is used by millions, making TypeMock a superstar. Anyway, a lot of people would start playing with these core possibilities, since it's like a new C#/VB version, everybody wants to try and see what else is possible with the new features.
Another thing is marketing. Currently it's "Isolator, the most powerful mock framework", and people, like, "why do I need a paid mock framework, I already have several free ones". With the TypeMock.Core it would be, "TMCore lets you break the language limitations", and people will go mad about it.