Background and concepts
The more I work on Parrots and the ideas I have about it, the more I manage to give it a narrow and precise context. This is an important step, because it helps users to decide if and when they should use Parrots instead of any other mocking library around.
IMHO, and given my experiences in the last years, I think that classic mocking works perfectly when you do "true TDD", but maybe you do not do TDD, for many reasons:
- you don't like it
- you like it, but developers around you do not
- you and developers like it, but your managers or company think it is a waste of time (sigh)
- you and everyone at your company like it, but then you don't manage to setup a true test driven development process, which indeed is not so easy to build and mantain
- ...
For whatever reason you don't do it, you end up working in a different way, and probably you keep on doing "unit tests" which supply concrete dependencies to your SUTs. They are not unit tests, they are more "integration tests", but they are done during development, and not after. They are not a good thing, we all know it, but there are times when they are the most and the best we can do. It happened to me to work in such a situation, and the only remedy we found to fix this wrong (and quite useless) context was to transform those integration test in unit tests introducing mocking "a posteriori", but often you have to sacrifice code coverage for the same reasons you did not introduce TDD from the beginning. And you really feel you are doing something wrong...
Now the idea is: you cannot do TDD, and you have to work with concrete dependencies, it would be great if "someone" would be able to transform our true dependencies in mock ones automatically, wouldn't it? That's where Parrots enters.
I already talked about this, but now what I want to concentrate on the mindset shift we have here. With classic mocking, you have to fully describe the behavior of your dependencies, because you may not have them yet, so you need a very good library to do it, and in "real world" scenarios your mocks are quite hard to setup. You must concentrate on what depencencies have to do and replicate it with enough precision to "fool" your SUT and make tests go green. With Parrots the mindset is different: you have the dependencies already, and you just want to remove them at a later time, so what you need is just a way to "record" conversations between SUT and dependencies, and to simulate them at a later time mantaining true fidelity with the real conversations. You must concentrate on recording call sequences with "high fidelity", and then on how two call sequences must be considered equivalent. This might not be an easy task, but it seems to me much more generic, because you don't have to deal with defining each call's behavior, but only with instructing someone (Parrots) about how it can distinguish call sequences, without having to deal with every single sequence. It seems to me much more 'declarative', don't you think?
Ok, Parrots is trying to follow this path, and I'm working on it day by day to implement this vision in a consistent way. I already cover several cases although not all of them yet, but I'm doing my best and I don't think it will get too much time.
I will talk more about details soon. Stay tuned :)