[rspec-users] should_redirect_to in advance - feels unnatural

Jay Levitt lists-rspec at shopwatch.org
Tue Nov 7 15:31:12 EST 2006

David Chelimsky wrote:
> On 11/7/06, Jay Levitt <lists-rspec at shopwatch.org> wrote:
>> I can understand that it's easier for rspec to set up a mock in advance
>> of the controller call.
> This was a philosophical choice, not a cop-out to make it easier to
> implement. That sounds more defensive than it is meant to be. I just
> want to assure you that our goal is to create the right API.

No, I completely understand...

>> But it makes it difficult to do something like:
>> context "The HarkController, given Louie the logged-in user" do
>>   setup do
>>     post :login, :username => 'louie', :password => 'atest'
>>   end
> The BDD way, at least as I see it, is rooted in the TDD way:
> 1. setup objects in a known starting state (setup - perhaps stubs)
> 2. set expectations of how the object should react to an action (mocks)
> 3. perform the action
> 4. verify that the object reacted as expected (verify mocks plus
> additional assert-like expectations)

I think the problem I'm having (and that David Lee is having as well) is 
that sometimes I'd like setup to involve an action.  It seems the answer 
may be that "the BDD way, at the controller-spec level, is to stub the 
initial action so you've got a known state."  I guess I've been writing 
semi-integration specs in that regard.
> The problem there is that it doesn't feel DRY. That's a problem I'm
> interested in solving, but I'd prefer to do it in a way that helps to
> express the behaviour-driven nature of BDD. What that means yet I'm
> not sure. I have a couple of ideas that I'll share as they become
> slightly more fully baked. I'd love to hear yours in the mean time.

I don't suppose "It worked in 0.6.4!" counts as an idea?

Seriously, I suspect that the arrival of integration specs may solve 
this, because it could be argued that I've really been writing 
integration specs if my specs involve two or more controller actions.  I 
would intensely dislike the person who argued that, because they'd be 
making me write more thorough controller-level specs and dive into 
mocking, but I'd probably forgive them when this made my code more robust.

Of course, the problem is that now I don't have the integration-like 
functionality that 0.6.4 had, so while I can create stubs to do the 
right thing at the controller level, I've lost the ability to test "X 
works after logging in".

> What I'm doing for examples like yours above is adding a method for
> the post and calling it from each of my specify blocks. Still not
> completely DRY, but it tells the story. And that is much more
> important to me than the risk of having to change something in more
> than one place in a spec.

To me, that's what "setup" was for - but, again, can setup legitimately 
be a controller action?  Mmmmmaybe.

In any case, as I just discovered, putting the login in a method call 
won't work, because rspec no longer likes two controller actions in a 
single spec, period.

> As for before or after the action, we did add
> controller.should_have_rendered for after. We could do something
> similar: controller.should_have_redirected_to. Or we could do what I
> originally had in there which was that should_render was smart enough
> to work on either side of the action. Looking at a few specs, I found
> that to be more confusing and, hence, split into 'before' and 'after'
> forms.
> Of these options, what do you like, and what not?

I would like "should_render" to be smart; I think the past-tense thing 
is confusing.  Ditto should_redirect_to.  But I don't have very strong 
feelings about that one.


More information about the rspec-users mailing list