El 09/07/2010, a las 04:25, Frank J. Mattia escribió:
>> Seems reasonable to me. You could test with either an interaction based
>> approach (use mocks and stubs to confirm that @object receives the
>> "created_by" message with the expected param) or a state based approach (hit
>> the controller action and then inspect the system state afterwards to
>> confirm that it is in the expected state).
>
> What I was trying to do on my own felt a lot like what you're calling
> an interaction based approach. I want to leave the behavior testing of
> my app to cuke features and I'm thinking that if I'm writing a
> controller spec, then it would probably be right to test the internals
> of my controllers.
I wouldn't say that "behavior" is only for Cucumber. Back when Cucumber hadn't
even been imagined yet, RSpec was created as a "Behavior-Driven Development"
library. Behavior has always been central to what we do with RSpec, even at the
lowest levels.
I think an important question to ask yourself when writing specs is "_Why_ am I
doing this?", and that leads on to "_What_ am I interested in specifying
here?". For me it's _all_ about behavior. The specs have two purposes, then: to
document/show the behavior (when read), and to confirm/test the behavior (when
executed). If I find myself writing a test that neither shows nor tests
behavior, then I probably shouldn't be writing it.
So, with the focus always on the behavior of the action, you can proceed to do
either interaction-based or state-based testing, depending on what feels right
for each particular case. As I mentioned in my earlier email, there are costs
and benefits of each approach, and long running debates about which method to
use when, but I think the important thing is to always try to use the best tool
for the job at hand.
> (As an aside, I've only been using RSpec for ~3
> weeks now and testing in general for maybe a month. All of this is
> pretty new to me... I find myself quickly becoming 'opinionated' about
> things so if any of this sounds like nonsense, a pointer in a good
> direction would be happily accepted.)
I think the best way to learn is to do what you're already doing: writing specs
(lots of them), _thinking_ about what you're doing, and when you have doubts
asking questions or looking for better ways. As time goes by you'll not only
get better at it, but your thinking will probably evolve too. I know I've gone
back and forth many times over the years, and sometimes I get a surprise when I
stumble over an old blog post of mine on testing and see what I posted.
I think if you look at what the most influential people in the Ruby/RSpec
testing community have been saying over the years, you'll see how _their_ ideas
have been metamorphosing and changing over the years too. It's a natural part
of thoughtful testing, I think.
El 09/07/2010, a las 06:07, Frank J. Mattia escribió:
> it "should explicitly set created_by" do
> controller.stub(:current_user) { mock_user }
> mock_order.should_receive(:created_by=).with(mock_user)
> post :create
> end
>
> This is my newly working spec. Does this look well thought out or is
> there some glaring pitfall to doing it this way?
Well, this is the way mocking and stubbing works. If you want to set an
expectation on an object that doesn't exist yet at the time you're setting up
the spec, you have to "chain" things so as to inject a mock of your own at the
right place, which you've done here. The amount of work you have to do setting
this up will vary from case to case.
This is one of the costs of the interaction-based approached, and you have to
weigh up that cost against the benefits.
Cheers,
Wincent
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users