Test data problem (in general and with acts_as_tree)

Hi all

I’m having problems with data in my specs - i’m probably just going
about
things the wrong way though.

I’m testing a model (called Property) that uses acts_as_tree, and for
now
have just done some specs for the basic acts_as_tree functionality -
just as
a sanity check, i thought, but i’m getting fails.

In a before(:all) block, i’m creating a bunch of objects and saving them
to
the database - like this:

describe Property, “with a fresh property tree” do
before(:all) do
@root = Property.new(:name => “Root”)
@root.id = 0 #root.id must be 0 for acts as tree to work properly
@root.save
@role = @root.children.create(:name => “Job Role”)
@dept = @root.children.create(:name => “Department”)
…etc
end

describe “,standard acts_as_tree methods,” do

#this test is failing
it "class.root" do
  Property.root.should eql(@root)
end

end

and the fail report from the above test:
‘Property with a fresh property tree ,standard acts_as_tree methods,
class.root’ FAILED
expected #<Property id: 0, parent_id: nil, name: “Root”>, got #<Property
id:
976, parent_id: nil, name: “Root”> (using .eql?)
./spec/models/property_spec.rb:50:
script/spec:4:

My problems seem to be arising from the fact that when i run the test,
the
objects i created last time are still in the database. Shouldn’t they
be
cleared out automatically? This in turn is preventing me from saving
root
with an id of 0. If i test all of this stuff in the console it works
fine,
but it’s failing in my tests, suggesting that my tests are broken. Am i
setting up my data in the wrong way?

My problems seem to be arising from the fact that when i run the test, the
objects i created last time are still in the database. Shouldn’t they be
cleared out automatically? This in turn is preventing me from saving root

I don’t know RSpec that well, but I’d guess before(:all) is run only
once in a describe block (and as such torn down only after the block
is finished), whereas before(:each) is run before every example (and
torn down respectively). So, I guess you’ll want to use before(:each)
version.

Was that it?


“One day, when he was naughty, Mr Bunnsy looked over the hedge into
Farmer Fred’s field and it was full of fresh green lettuces. Mr
Bunnsy, however, was not full of lettuces. This did not seem fair.”
– Terry Pratchett, Mr. Bunnsy Has An Adventure

On Tue, Feb 26, 2008 at 5:41 AM, Edvard M. [email protected]
wrote:

Was that it?
Yep. Use before(:each) and all should be well.

I’m using before(:all) because i want to create a single ‘family’ of
tree
objects and then run tests against it. If i have all the object
creation as
a before(:each) then the database will be even more full of
duplications,
won’t it?

My problem, though, is that the data is left over from the last time (in
fact all previous times) that i ran the spec file, where i thought that
it
was cleared out. Do i need to explicitly tell the database to clear all
the
records in an ‘after’ block?

On 26/02/2008, David C. [email protected] wrote:

On Tue, Feb 26, 2008 at 7:39 AM, Max W.
[email protected] wrote:

This does not happen for you implicitly when you use before(:all)
because there is no mechanism for running a group of examples in a
transaction.

ah…i see. I didn’t know about that last bit. :slight_smile:

Please beware that this approach is extremely error prone over time.
If you ever introduce a side effect (intentionally or accidentally)
that modifies the data, you’re going to look at the spec, see the data
you’re setting up and incorrectly think that that’s the data every
example is using. It is much, much safer (and more sane) to use
before(:each) even though it may slow things down a bit.

Gotcha. Thanks!

HTH,

On Tue, Feb 26, 2008 at 7:39 AM, Max W.
[email protected] wrote:

I’m using before(:all) because i want to create a single ‘family’ of tree
objects and then run tests against it. If i have all the object creation as
a before(:each) then the database will be even more full of duplications,
won’t it?

No. If you have use_transactional_fixtures set to true, each example
is run in a transaction, which is rolled back at the end of the
example.

This does not happen for you implicitly when you use before(:all)
because there is no mechanism for running a group of examples in a
transaction.

My problem, though, is that the data is left over from the last time (in
fact all previous times) that i ran the spec file, where i thought that it
was cleared out. Do i need to explicitly tell the database to clear all the
records in an ‘after’ block?

Yes. If you want to use before(:all) to set up data, you need to use
after(:all) to clean it up explicitly.

Please beware that this approach is extremely error prone over time.
If you ever introduce a side effect (intentionally or accidentally)
that modifies the data, you’re going to look at the spec, see the data
you’re setting up and incorrectly think that that’s the data every
example is using. It is much, much safer (and more sane) to use
before(:each) even though it may slow things down a bit.

HTH,
David

hehe, tbh even if the documentation had been there i probably wouldn’t
have
read it :slight_smile:

thanks!

On Tue, Feb 26, 2008 at 8:08 AM, Max W.
[email protected] wrote:

This does not happen for you implicitly when you use before(:all)
because there is no mechanism for running a group of examples in a
transaction.

ah…i see. I didn’t know about that last bit. :slight_smile:

FYI: http://rspec.lighthouseapp.com/projects/5645-rspec/tickets/310

Cheers,
David

Yeah but then I get to say RTFM. Right now, TFM doesn’t exist :frowning:

rant << EOF

Indeed. People see much trouble in writing documentation so that they
don’t have to answer the same questions ad nauseam.
It would be nice if we appreciated their efforts and check the
documentation first.

EOF


“One day, when he was naughty, Mr Bunnsy looked over the hedge into
Farmer Fred’s field and it was full of fresh green lettuces. Mr
Bunnsy, however, was not full of lettuces. This did not seem fair.”
– Terry Pratchett, Mr. Bunnsy Has An Adventure

On Tue, Feb 26, 2008 at 8:31 AM, Max W.
[email protected] wrote:

hehe, tbh even if the documentation had been there i probably wouldn’t have
read it :slight_smile:

Yeah but then I get to say RTFM. Right now, TFM doesn’t exist :frowning: