Hi gang. I've come across what I believe to be unexpected behavior for some of my before :each blocks, and I wonder if anyone can enlighten me as to why this is happening.
The surprising thing happens when I run a 'before :each' inside of an each block on a Hash. I have a #before_save hook in my ActiveRecord model. When I call @sample_model.save from the before block, the model runs a uniqueness validation. However, when I save from within the example, the save works fine. Below is the minimal test case I was able to put together: class SampleClassMigration < ActiveRecord::Migration def self.up create_table :sample_classes do |t| t.string :sample_field t.string :attrib_1 t.string :attrib_2 end end end class SampleClass < ActiveRecord::Base validates_uniqueness_of :sample_field before_save :prep def prep self.sample_field = 'sample_value' end end describe SampleClass do EXAMPLES = { :attrib_1 => 'foo', :attrib_2 => 'bar' } EXAMPLES.each do |key, value| before(:each) do @sample = SampleClass.new(key => value) #In the passing case, this call to #save #is moved into the 'it' block @sample.save end it "key : #{value}\tvalue : #{key.to_s}" do #in the other case, I call the spec here @sample.should be_valid end end end It was my expectation that calling an instance method in the before block would be the same as calling it within the example block. Instead, I get two different results. When called from within the it block, both examples pass. When called from within the before block, they both fail: 1) 'SampleClass key : bar value : attrib_2' FAILED Expected #<SampleClass id: 2, sample_field: "sample_value", attrib_1: "foo", attrib_2: nil> to be valid, but it was not Errors: Sample field has already been taken ./spec/models/minimal_spec.rb:20: 2) 'SampleClass key : foo value : attrib_1' FAILED Expected #<SampleClass id: 2, sample_field: "sample_value", attrib_1: "foo", attrib_2: nil> to be valid, but it was not Errors: Sample field has already been taken ./spec/models/minimal_spec.rb:20: I'm surprised to see that the example fails, but I'm more surprised to see that it fails both times. It is apparently the case that the "before" block is executed on every iteration of the "each" block (but that the examples themselves are executed later). 1) Is this a bug? 2) Is it a known behavior? 3) Is there a "BDD-theoretical" better way to do something like this (assuming a larger hash of examples, for instance)? I'm using: gem 'rails', '2.3.5' gem 'mysql' group :development, :test do gem 'database_cleaner' gem 'rspec-rails', '1.3.2' gem 'rspec', '1.3.0' end DatabaseCleaner is properly configured, and runs for many other specs. (Indeed, it even runs correctly between steps, as demonstrated by the case where the specs pass). Thanks, Andrew Kasper
_______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users