On Wed, Feb 18, 2009 at 6:06 PM, Zach D. [email protected]
wrote:
it {should valdate_presence_of(:login)}
behind a nice declarative interface, will you not care about having
examples showing that your objects utilize that behaviour?
That’s a huge “depends” but yeah, basically. I don’t really test code
that can’t possibly break. Declarative code like Rails validations or
associations can’t possibly break*, it can only be removed. Don’t
remove it unless you need to then, right?
I came to this conclusion re: validations/assocations by observing the
evolution of how people write specs for them. You start off doing
something like:
describe User do
it “should require a name” do
User.new(:name => ‘’).should have_at_least(1).error_on(:name)
end
end
and after you write a bunch of those you look for a way to DRY up your
specs a bit so you write some kind of custom matcher. Make it nice
and concise and you end up with shoulda macros:
describe User do
should_require_attributes :name
end
You could literally write a couple lines of adapter code that would
take this specification and generate the production class!
def describe(klass, &block)
(class << klass; self; end).class_eval do
alias_method :should_require_attributes, :validates_presence_of
end
klass.class_eval &block
end
What does it give you?
I’m looking at the shoulda examples and chuckling at how ridiculous
the AR ones are (controller ones are nice, they use macros for stuff
that you can’t program declaratively).
class PostTest < Test::Unit::TestCase
should_belong_to :user
should_have_many :tags, :through => :taggings
should_require_unique_attributes :title
should_require_attributes :body, :message => /wtf/
should_require_attributes :title
should_only_allow_numeric_values_for :user_id
end
and in AR (not 100% sure this makes it pass, I’m just writing, you get
the idea)
class Post < ActiveRecord::Base
belongs_to :user
has_many :tags, :through => :taggings
validates_uniqueness_of :title
validates_presence_of :body, :title
validates_format_of :message, :with => /wtf/
validates_numericality_of :user_id
end
There are two types of specification that I’ve found useful:
declaration and example. Rails association and validation macros are
specification by declaration. RSpec gives us specification by
example. Effectively this means that a class’s specification is split
between its implementation (declarative parts) and RSpec examples.
If your code is specified declaratively, you don’t need to write
examples.
Not testing things that have no logic makes sense. However, validation
methods have logic, it’s just wrapped up behind a nice interface.
Sure but can that logic break?
Pat
- Associations can break via changes to the db, but that will get
caught by other specs or acceptance tests that make use of the
associations