Peter Laurens wrote:
First, my model looks like this:
Author <-HABTM-> Paper
With a model named 'authors_papers' which belongs_to :author and :paper. This is to act as a lookup table which I believed Rails would do automatically if set up like this.
In addition to other comments...
If by "Model" you mean a first-class object with more variables than just the two IDs, you shouldn't use has_and_belongs_to_many. You should use:
class Author... has_many :authors_papers has_many :papers, :through => :authors_papers
This implies you should give authors_papers.
However, if you said "Model" because you mean "table", and that table owns no data for itself, then use habtm!
This is my testing code, testing the Author model:
This test case is too long. Short test cases are the key to happiness.
[code] # Tests the Author<->Paper linkage through the automatic use of # the author_papers model by Rails. a = Author.new p = Paper.new
Those should be in the fixture system.
assert_not_nil a assert_not_nil p
Don't assert something if another line will incidentally assert it. And we wouldn't get very far in this test if either of those were nil.
And give them complete names.
assert a.save assert p.save
By and large tests should save with save!. That satisfies the assertion concept by exploding if it can't save. Further, save! will emit a diagnostic declaring why we could not save, and 'assert' will only say "false is not true".
# 1. Does the linkage work, returning an empty set? assert_equal a.papers,
Yes it's harmless to add assertions that learn how Rails plumbing works!
# 2. Can we assign a paper to the author? assert a.papers << p assert a.save assert_not_equal a.papers,
Would this work?
assert_equal [p], a.papers
I suspect you can force a reload on a collection by passing (:reload) to its successor. I have not confirmed this, so someone must speak up if I'm wrong!
In general, prefer positive statements to negative ones, including positive "assert_equals" instead of negative "assert_not_equal".
I also suspect one can pass (true), but that's not self-documenting.
Also, you should put the "reference" on the left side of an assertion, and the "sample" on the right. There are numerous trivial reasons to do this; just do it because there are _no_ good reasons to put the reference on the right!
# 5. Can we update through the link? assert p.authors.first.update_attributes(:lastname => "abc") # Succeeds
Thanks for the reminder that I should tack assert onto the beginning of all my test cases' update_attributes calls!
Now that you have experienced the joy of writing assertions for behavior that's already written, you are going to have major fun writing tests for your own new code. More fun than endless debugging, at least!