On 15 Mar 2009, at 16:52, Ben Mabey wrote:
I know what you mean, and it would certainly make for nice readable
scenarios. My worry is how maintainable the steps would be in the
long run. I'm used to seeing steps like this:
Given /the Policy has a secondary risk/ do
Policy.count.should == 1
policy = Policy.first
policy.secondary_risk = true
policy.save
end
Which are pretty explicit and leave no room for accidental abuse.
What the OP suggested would give you something more like this:
Given /a Policy/ do
@it = Factory(:policy)
end
With /a secondary risk/ do
@it.secondary_risk = true
@it.save
end
I dunno actually. Now I type it out it doesn't seem so bad :)
As previously mentioned in the thread another way to phrase this is
with step tables. Here is the code I use:
http://gist.github.com/59007 (related blog post:
http://www.benmabey.com/2009/02/05/leveraging-test-data-builders-in-cucumber-steps/)
I have been using instance variables in my steps (but naming them
after the model, i.e. @policy) but Matt's DB solution is nice in
some respects. Both ways fall apart when you have multiple polices,
but in that case you should probably be passing in the name or some
other identifying aspect of the model. Anyways, it seems like a
pattern is emerging on how to carry state to other steps when you
have to. I was bored so I combined both approaches:
module ObjectLocators
def the_policy
if @policy
@policy
else
case Policy.count
when 0
raise "There is no @policy variable defined and no policy in
the DB! Establish state in previous step or create a new policy."
when 1
Policy.first
else
raise "There are multiple policies in DB and no @policy
variable set! Please disambiguate the state in previous step."
end
end
end
end
World { |world| world.extend(ObjectLocators) }
(this code is here: http://gist.github.com/79470)
Like I said, I was bored and haven't really tried this. I don't
know if I even like it, but I thought extracting out the patterns
would be useful. You could leverage factories just as I do in my
previous gist to provide locator (locater?) for all of your models.
We have some very similar code deep in the bowels of Songkick's
features folder that is a little scrappy, but does help us solve this
problem quite nicely.
Basically there's a regular expression that matches on phrases of the
following form:
the Widget
the Widget "Foo"
"Foo"
So you can use that in your step matchers like this:
When /I delete (#{THE_THING})/ |identifier|
thing_to_delete = identified_model(identifier)
end
If you want to remember something just by the "Foo" label, you have to
throw it into a collection, imaginatively named 'stuff', as you do so:
stuff["Foo"] = Factory(:widget, :name => "Foo")
As I say it's a little scrappy as it's something we threw together
ages ago and haven't really felt the need to revisit, but hopefully it
will give someone some ideas:
http://gist.github.com/79496
Matt Wynne
http://blog.mattwynne.net
http://www.songkick.com
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users