# Assertion doesn't make sense (to me)

**URL:** <https://www.ruby-forum.com/t/assertion-doesnt-make-sense-to-me/116440>\
**Category:** Rails\
**Created:** [October 5, 2007, 3:53pm UTC](https://www.ruby-forum.com/t/assertion-doesnt-make-sense-to-me/116440 "2007-10-05T15:53:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jazcyk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e56c9b/32.png) [@jazcyk](https://www.ruby-forum.com/u/jazcyk)\
**Post date:** [October 5, 2007, 3:53pm UTC](https://www.ruby-forum.com/t/assertion-doesnt-make-sense-to-me/116440/1 "2007-10-05T15:53:26Z")

</div>

Hi, I am just starting out writing unit tests, and perhaps someone could  
be kind enough to explain why I am seeing this behaviour:

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.

This is my testing code, testing the Author model:

```auto
# Tests the Author<->Paper linkage through the automatic use of
    # the author_papers model by Rails.
    a = Author.new
    p = Paper.new
    assert_not_nil a
    assert_not_nil p
    assert a.save
    assert p.save

    # 1. Does the linkage work, returning an empty set?
    assert_equal a.papers, []

    # 2. Can we assign a paper to the author?
    assert a.papers << p
    assert a.save
    assert_not_equal a.papers, []

    # 3. Can we pull that paper out (read) again?
    assert a.papers.include?(p)

    # 4. Can we find the author from the paper?
    assert_not_nil p.authors
    assert p.authors.include?(a)

    # 5. Can we update through the link?
    assert p.authors.first.update_attributes(:lastname => "abc") #
Succeeds
    assert_equal("abc", p.authors.first.lastname) #
Succeeds
    puts "A.Lastname: #{a.lastname}" # =>
<nil>
    puts p.authors.first.lastname # =>
abc
    assert_equal a, p.authors.first #
Succeeds
    assert_equal("abc", a.lastname) #
Fails!

```

The problem is in the last assertion - surely a.lastname should be set  
to ‘abc’ as we did that through the relationship from the Paper? Any  
help would be much appreciated, thanks.

---

<div class="post-metadata">

**Author:** ![jazcyk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e56c9b/32.png) [@jazcyk](https://www.ruby-forum.com/u/jazcyk)\
**Post date:** [October 5, 2007, 4:39pm UTC](https://www.ruby-forum.com/t/assertion-doesnt-make-sense-to-me/116440/2 "2007-10-05T16:39:31Z")

</div>

On 5 Oct 2007, a

> Succeeds  
> assert\_equal(“abc”, a.lastname) #  
> Fails!
> 
> [/code]
> 
> The problem is in the last assertion - surely a.lastname should be set  
> to ‘abc’ as we did that through the relationship from the Paper? Any  
> help would be much appreciated, thanks.

The problem is that a contains stale data (it corresponds to the same  
row in the database as p.authors.first, but it’s a different ruby  
object(.  
If you did a.reload before the assertion, the test should pass. The  
compare on active record just compares the primary key, not the  
attributes, which is why assert\_equal a, p.authors.first

Fred

---

<div class="post-metadata">

**Author:** ![jazcyk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e56c9b/32.png) [@jazcyk](https://www.ruby-forum.com/u/jazcyk)\
**Post date:** [October 5, 2007, 5:08pm UTC](https://www.ruby-forum.com/t/assertion-doesnt-make-sense-to-me/116440/3 "2007-10-05T17:08:52Z")

</div>

> The problem is that a contains stale data

Aha - I had suspected it was something like this but my unfamiliarity  
with Rails prevented me from discovering the actual culprit.

Thanks a lot for your time taken, it’s much appreciated,

- N

---

<div class="post-metadata">

**Author:** ![jazcyk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e56c9b/32.png) [@jazcyk](https://www.ruby-forum.com/u/jazcyk)\
**Post date:** [October 5, 2007, 5:13pm UTC](https://www.ruby-forum.com/t/assertion-doesnt-make-sense-to-me/116440/4 "2007-10-05T17:13:02Z")

</div>

Peter L. 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!

–  
Phlip  
[http://www.oreilly.com/catalog/9780596510657/](http://www.oreilly.com/catalog/9780596510657/)  
^ assert\_xpath

---

<div class="post-metadata">

**Author:** ![jazcyk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/e56c9b/32.png) [@jazcyk](https://www.ruby-forum.com/u/jazcyk)\
**Post date:** [October 5, 2007, 5:17pm UTC](https://www.ruby-forum.com/t/assertion-doesnt-make-sense-to-me/116440/5 "2007-10-05T17:17:22Z")

</div>

Phlip - thanks for you comments, will help me improve my testing a great  
deal.

- N
