Appropriately unit testing my models?

Can anyone point me towards a good resource on appropriately testing all
the fields in a given model? Or perhaps give some advice.

For example, this test below is for a model with only a single column,
but when I add a new column (a date field for example), how would I
extend the test to cover both the body and date column of the model?

def test_that_status_note_body_is_valid
note = Note.new
# Empty body field
assert !note.valid?
assert note.errors.invalid?(:body)
note.body = nil
# Nil body field
assert !note.valid?
assert note.errors.invalid?(:body)
note.body = “Testing body that should pass”
# Correct body field
assert note.valid?
assert !note.errors.invalid?(:body)
end

Would I create a new test called “test_that_date_is_valid” and only test
against that or would I create tests that build instances of “Note” that
contain as many test cases as it would take to test against every case?
(which seems correct but when I think about how many tests would be
involved for a model with even 5 columns it then seems to look not so
correct)

I appreciate the responses, thanks!

Matthew W. wrote:

assert !note.valid?

Would I create a new test called “test_that_date_is_valid” and only test
against that or would I create tests that build instances of “Note” that
contain as many test cases as it would take to test against every case?
(which seems correct but when I think about how many tests would be
involved for a model with even 5 columns it then seems to look not so
correct)

I appreciate the responses, thanks!

Maybe you’re can use a generic new method - something like:

def test_status_for_something
note = new_note(:body => nil)

end

def new_note(options)
Note.new({:body => “Default body”, :header => “Default header”, :date
=> Date.today}.merge(options))
end

Btw, I suggest that you split your testcases into smaller pieces, the
above could be split into test_body_should_be_invalid_when_nil,
test_body_should_be_invalid_when_empty_string,
test_body_should_be_valid_when_nonempty_string.

Makes it easier to spot the problem when a test breaks.


Cheers,

  • Jacob A.

Try something like

class TestModel < Test::Unit::TestCase
def setup
@model_instance = Model.new
end

add here whatever you can think as empty value

def test_should_not_body_be_empty
assert_error_on @model_instance, :body, :body => nil
assert_error_on @model_instance, :body, :body => “”
end

TODO: clean up this to use the first key of values hash as field

def assert_error_on(model, field, values = {})
# there is no assert here cuz others field may have errors
# and the idea is test one thing at time.
model.valid?
assert not model.errors[field].nil?
end

TODO: clean up this to use the first key of values hash as field

def assert_no_errors_on(model, field, values = {})
# there is no assert here cuz others field may have errors
# and the idea is test one thing at time.
model.valid?
assert model.errors[field].nil?
end
end

Try to keep your tests clean, do one thing at time, and reflect that
thing
in the test name. And add as many test you need. Always remember
that Test Cases are classes so add helper method to avoid repetitive
tasks
is not only good, its a must.

With this idea in mind test something like this:

class Model < ActiveRecord::Base
validates_presence_of :name
validates_length_of :name, :in => 4…128
validates_uniqueness_of :name
end

will take at least one test per validation, but you probably wrote the
tests first right? :stuck_out_tongue:

On Oct 1, 3:36 pm, Matthew W. [email protected]