On 2008-10-08, at 07:01, Jeroen van Dijk wrote:
Hi all,
I'm new to this list and new to RSpec so I have been trying out
RSpec the last couple of days and I find it very a natural way of
testing. So first of all thanks for providing this framework.
Now, I have written some tests for my controllers and models and I
saw myself writing similar code, so I began refactoring and came up
with the following issue.
Here is a simple example of what I first wrote:
describe Example do
it "should not be valid without attribute1" do
Example.new(:attribute2 => "2").should_not be_valid
end
it "should not be valid without attribute2" do
Example.new(:attribute1 => "1").should_not be_valid
end
end
Which I rewrote into another working test:
######
module ExampleSpecHelper
def required_valid_attributes
{:attribute1 => "1", :attribute2 => "2"}
end
end
describe Example do
include ExampleSpecHelper
[:attribute1, :attribute2].each do |attribute|
before(:all) do
@model_with_one_missing_attribute =
TextMessage.new(required_valid_attributes.except(attribute))
end
it "should not be valid without #{attribute}" do
@model_with_one_missing_attribute.should_not be_valid
end
end
#####
In this example in you might not see difference in lines of code,
but imagine you would have 10 attributes and 10 more tests for each
attribute.. Now I rewrote this I was still not satisfied because I
thought I would like to use this same approach for several models
with different attributes while keeping the logic of this test in
one place. Unfortunately, I didn't come that far because of this:
#this works:
describe Example do
include ExampleSpecHelper
required_attributes = [:attribute1, :attribute2]
required_attributes.each do |attribute|
before(:all) do
@model_with_one_missing_attribute =
TextMessage.new(required_valid_attributes.except(attribute))
end
it "should not be valid without #{attribute}" do
@model_with_one_missing_attribute.should_not be_valid
end
end
#However this which eventually will be more DRY, but does for some
reason not work?!
module ExampleSpecHelper
...
def required_attributes
[:attribute1, :attribute2]
end
...
end
describe Example do
include ExampleSpecHelper
required_attributes.each do |attribute|
before(:all) do
@model_with_one_missing_attribute =
TextMessage.new(required_valid_attributes.except(attribute))
end
it "should not be valid without #{attribute}" do
@model_with_one_missing_attribute.should_not be_valid
end
end
############
I don't understand why it does not work. In the last example
required_attributes is nil while the other methods from the helper
module such as 'required_valid_attributes' are available on an even
lower level. Why? I hope you understand why I'm trying to refactor
it like this. If I can do this I only need to define the required
attributes for each model and use it_should_behave_like "an AR
model" to keep it DRY.
Hope someone can clarify this and that I haven't done something
stupid! Thanks!
Cheers,
Jeroen
Hi Jeroen. As I was getting into RSpec and writing specs for my
various models, I too found that my code could be a lot DRYer. I ended
up writing a module that generates specs for my model attributes. I've
put it up on GitHub, along with full, lengthy example of how to use
it. Have a look:
http://github.com/nickhoffman/modelspeccer/
Cheers,
Nick
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users