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 rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users