On Jan 22, 2008 10:26 PM, David C. [email protected] wrote:
Now I’d like to assure that any subclass of this class also passes
…
I usually stick w/ shared example groups, but I sometimes use an
iterator like this. Not sure why. I’ll think about it.
I think using an iterator here is weird, and muddles the intent of the
specs.
Think of what it means to define a class and a subclass.
class Foo
… some behavior …
end
class Bar < Foo
… all of Foo’s behavior …
… some specialized behavior …
end
You don’t define all the behavior in Bar - you get a bunch of it from
Foo for free, and then specialize whatever you need. Your specs
should be similar in spirit.
shared_examples_for(“the foo role”) do
it “should have some behavior”
…
end
describe Bar do
it_should_behave_like “the foo role”
it “should have some specialized behavior”
…
end
That is far more clear to me. The downside is that you also end up with
On Jan 22, 2008 10:26 PM, David C. [email protected] wrote:
Now I’d like to assure that any subclass of this class also passes
…
I usually stick w/ shared example groups, but I sometimes use an
iterator like this. Not sure why. I’ll think about it.
I think using an iterator here is weird, and muddles the intent of the
specs.
Think of what it means to define a class and a subclass.
class Foo
… some behavior …
end
class Bar < Foo
… all of Foo’s behavior …
… some specialized behavior …
end
You don’t define all the behavior in Bar - you get a bunch of it from
Foo for free, and then specialize whatever you need. Your specs
should be similar in spirit.
shared_examples_for(“the foo role”) do
it “should have some behavior”
…
end
The downside is you end up with
describe Foo do
it_should_behave_like “the foo role”
end
to specify the behavior, which feels pretty weak to me.
Though I assume you feel somewhat similarly, so I’d be interested to
know when you use an iterator for full example groups.
Actually one example I remember is when I wrote a macro that added a
bunch of methods to a class…I wrote the initial example group for
just one attribute name. Then when I extracted the macro, I just
iterated through a bunch of names over the example group. So it can
be useful. Although a whole class feels too coarse grained for that
approach, to me.
I do use iterators a bunch for stuff like
[:name, :email, :phone, :address].each do |field|
it “should require a #{field}” do
u = build_user(field => nil)
u.should_not be_valid
u.should have(1).error_on(field)
end
end
Also, since I’m close to the subject, here’s a little tip. I’ve seen
people write specs like:
it “should require valid attributes” do
[:name, :email, :phone, :address].each do |field|
u = build_user(field => nil)
u.should_not be_valid
u.should have(1).error_on(field)
end
end
but that sucks, because if the example fails, you don’t have any clue
why. Cause it’ll just say that user is invalid, but doesn’t tell you
which field is blank.
That was a bit of a tangent. It’s late, I’m loopy
Pat