Jonathan L. wrote:
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users
Jonathan,
You can do this, and I have done it in the past, but I wouldn’t
recommend it. Their are a couple of reasons why I would discourage it.
The first is that by just posting a hash to the form’s URL (like you
would do in a controller spec) you are not verifying the existence of
the form fields and thereby skipping the view layer of the stack. You
can get around this by also checking the markup for the form fields like
you would in a view spec. However, doing this becomes very tedious. A
much better solution exists and that is webrat. Webrat offers a very
nice interface that ends up verifying the existence of the form fields
and doing the post for you. If you haven’t looked into webrat then I
would highly recommend it.[1]
The other disadvantage of what you are doing is that you might be
placing too much information in your stories. The danger of this is
that you might end up with ugly stories with a lot of noise that end up
drowning out the real ‘signal’ of the story. Additionally, every time
you add a field to the form you will have to change the story. See my
post about the different styles of writing styles to see an example of
how you might rewrite it. [2]
That said, I don’t know your exact situation and what you are trying to
do may very well be the best approach to it. So, the answer to your
real question would be something like:
Pass the params as such: ISBN: ‘0967539854’ and comment: 'I love
this book’ and rating: ‘4’
this matcher will post to the resourcese default create action
When “$actor submits $a_or_an $resource with $attributes” do |actor,
a_or_an, resource, attributes|
post_via_redirect “/#{resource.downcase.pluralize}”,
{resource.downcase => attributes.to_hash_from_story}
end
class String
Coverts a string found in the steps into a hash. Example:
ISBN: ‘0967539854’ and comment: ‘I love this book’ and rating: ‘4’
=> {“rating”=>“4”, “isbn”=>“0967539854”, “comment”=>"I love this
book"}
def to_hash_from_story
self.split(/, and |, /).inject({}){ |hash_so_far, key_value|
key, value =
key_value.split(“:”).map{ |v| v.strip.gsub(" “,”_")}
hash_so_far.merge(key.downcase => value.gsub(“'”,“”))
}
end
end
To reiterate, I really do not like the pattern above. I started out
doing stories like that ran into many problems with it. In short I
think step reuse is overrated.
I hope that helps,
Ben
[1]
http://www.benmabey.com/2008/02/04/rspec-plain-text-stories-webrat-chunky-bacon/
[2]
http://www.benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories/