Assertion doesn't make sense (to me)

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.

# Tests the Author<->Paper linkage through the automatic use of
    # the author_papers model by Rails.
    a =
    p =

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.


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_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") #

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!