[rspec-users] Problem testing method
dchelimsky at gmail.com
Thu Sep 25 09:58:03 EDT 2008
On Thu, Sep 25, 2008 at 8:09 AM, Carlos Rafael Belizón Ibáñez
<paliyoes at gmail.com> wrote:
> El jue, 25-09-2008 a las 12:44 +0100, Matt Wynne escribió:
>> Have a look at this:
>> When you call foo -= 1, ruby does two things:
>> (1) asks foo for its value
>> (2) tells foo to have a new value, one less than the answer it got
>> back from the first question.
>> If you re-write more verbosely, you'll see what I mean:
>> foo = foo - 1
>> Two operations are being done to foo. So if you want to mock out foo,
>> you have to mock out both those operations.
>> Make sense?
>> In case you wondered: The opinions expressed in this email are my own
>> and do not necessarily reflect the views of any former, current or
>> future employers of mine.
>> rspec-users mailing list
>> rspec-users at rubyforge.org
> Thanks. I'm understand what I must do to test this type specifications.
> I changed my code and now it's work fine, but I have one question:
> What way it's better to test this method? Using a real instance of game,
> or using a mock?
It's difficult to say which one is better without more context. There
are risks, costs and benefits to each approach and they are not the
same in every situation. But I can give you some things to think about
and evaluate given the rest of your code base and where you are in the
process of developing it.
If the game has a lot of associations and validation requirements, it
could be complicated to set up in the code example (costing you time)
and expensive to run (costing you more time every time you run the
suite). This suggests using a mock might serve you better in that
situation, but if you do so without any higher level integration
tests, then you introduce the risk of having all of your code examples
pass but the application falls apart because you changed something in
the real Game that didn't reveal itself via the mock Game.
Also, and this is both very important and very subtle, tools like
rspec and processes like TDD and BDD aren't only about artifacts (the
resulting code), but they are about process. For example, if you
choose to develop a Lineup object before the Game object is developed,
using a mock Game can help you stay focused on the Lineup and also
help you to discover what APIs and services the real Game will need to
Using mock objects as part of your process encourages a smaller
surface area and, therefore, a higher level of decoupling between
objects. First, since you don't have a real object at hand, you can
not access its internals. Second, since you're developing the API for
the Game (in this example) from the perspective of the Lineup that
uses it, you're pushed to thinking of the surface of the Game and the
relationship between consumer and supplier (you could say client and
server, but those terms are overloaded). Discovering APIs by exploring
interactions is a great way to improve the chances that you get usable
When you do this the other way, working on the Game first and thinking
"gee, I wonder what services other objects might need ... I'll add
these 20 things ..." you end up with some APIs that totally hit the
mark, some that just miss the mark, resulting in either re-work or,
worse, living with a less than ideal API. And you end up with some
APIs that are just never, ever used.
All of that said, you're working in a situation in which you've
already developed the code and you are trying to backfill tests onto
it - the antithesis of TDD. So in this case you won't get any of the
process and discovery benefits that you would had you developed things
test first. Which leaves you really deciding based on the risks of not
having your granular examples function as integration tests vs the
time it takes to run them.
That's a lot, but I hope this is helpful.
> Thanks ;).
> rspec-users mailing list
> rspec-users at rubyforge.org
More information about the rspec-users