On 3/16/08, David Chelimsky <[EMAIL PROTECTED]> wrote:
> On Fri, Mar 14, 2008 at 8:12 PM, Rick DeNatale <[EMAIL PROTECTED]> wrote:
> > 2) Having figured that out and moving on, I now have another
> > problem, which is what's the best way to clean up the database so that
> > Scenario A can run again if it assumes that the stuff it put in the DB
> > isn't there each time it runs. Cleaning the DB after running the
> > scenario won't work since it defeats the purpose of using the scenario
> > as a pre-condition. Cleaning it before is more difficult,
> > particularly if I'm using parameterized steps. It would be nice if I
> > could somehow use database transactions, but I don't see a nice way to
> > do that either.
>
>
> This should just work. If you look at story_adapter.rb, which defines
> the RailsStory class (maybe we should align :) ) you'll see that the
> transaction is opened when the scenario starts and rolled back when it
> is finished. GivenScenario should not result in a call to any of the
> scenario finished methods (scenario_succeeded, _pending, _failed), so
> it should get rolled back.
I've gotten stuck here.
To recap, when I don't make the story a RailsStory, then the the first
scenario (A) works but fails when invoked from B as a GivenScenario.
One of the steps is failing because of a validates_uniqueness in on
of the models which fails because of stuff left in the DB from the
initial running.
When I change it to a RailsStory then Scenario A fails in the same
step the FIRST time. In this case it's because records which it needs
aren't there.
The records in question have been loaded by a helper which calls
Fixtures.create_fixtures to load them. These particular tables are
basically 'constants' for the app.
A few more tidbits.
There's are models called Role, Membership, and a join model MembershipRole
Role
has_many :membership_roles
has_many :memberships :through => :membership_roles
end
Membership
has_many :membership_roles
has_many :membersships, :through => :membership_roles
end
MembershipRole
belongs_to :membership
belongs_to :role
validates uniqueness_of :role_id, :scope => :membership_id
end
Role has a class method get which takes a string and effectivly does this:
def self.get(name)
@role_objects ||= {}
@role_objects[name] ||= find_by_name(name)
end
And the method ultimately invoked by the failing step has a skeleton like this:
class Membership < ActiveRecord::Base
def add_role(name)
if role = Role.get(name)
...
else
raise "Can't find Role named #{name}
end
end
If I change the Role.get method to bypass the cache then the exception
gets raised the first time the step is executed for a RailsStory, and
second time for a non-RailsStory.
With that method left alone, the Role objects are found at some time
previous to the step and cached, in which case the failure happens
inside the if where a simplified version of that ... looks like this:
unless self.roles(true).include(role)
membership_role = MembershipRole.create(:membership => self,
:role => role)
end
role.dependencies.each {|dependency| add_role(dependency)
The problem is that the validates_uniqueness_of in MemberRole is
failing, again the second time the step in question is called for a
non-RailsStory, and the first time for a RailsStory. The reason is
that the query generated by the roles association is doing a join on
roles and membership roles and the roles aren't in the DB, but then
validates_uniqueness of just checks the membership_id and role_id
fields.
It looks to me as though running as a RailsStory is causing the roles
records to be deleted before the scenario runs, but after the class
cached them. s
Any ideas?
--
Rick DeNatale
My blog on Ruby
http://talklikeaduck.denhaven2.com/
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users