# Unit testing models with relationships between tables

**URL:** <https://www.ruby-forum.com/t/unit-testing-models-with-relationships-between-tables/110548>\
**Category:** Rails\
**Created:** [July 27, 2007, 1:12pm UTC](https://www.ruby-forum.com/t/unit-testing-models-with-relationships-between-tables/110548 "2007-07-27T13:12:41Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [July 27, 2007, 1:12pm UTC](https://www.ruby-forum.com/t/unit-testing-models-with-relationships-between-tables/110548/1 "2007-07-27T13:12:41Z")

</div>

Hi,

I’m quite new to Rails but even newer to the idea of unit testing as  
all the things I have done so far have been relatively small and so I  
haven’t bothered with unit tests. I’m just embarking on a much bigger  
project and wanted some advice as to testing strategies.

I’ve been following the testing chapter in Agile Web D. With  
Rails by the Pragmatic Programmers and I’ve been getting on ok with  
that but I’m not sure how to test models that have relationships  
between them.

For instance I have one model, ModelA say that belongs to another,  
ModelB. I would like to use fixtures to preload some data; how do I  
get the unit test for ModelA to load the fixture data for ModelB so  
that I can perform the tests with the table dependencies in place? How  
do I specify the foreign key value in the ModelA fixture so that it  
refers to a record in ModelB?

What are the strategies when it comes to testing models with  
relationships between tables? Do you just test as if there was no  
relationship and use dummy values for foreign key fields or should the  
relationships also be tested?

Also on a separate note, is there any point testing all the default  
validations implemented by rails when they are themselves tested as  
part of the rails framework?

Thanks in advance,  
Toby

---

<div class="post-metadata">

**Author:** ![casper\_the\_ghost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/58956e/32.png) [@casper\_the\_ghost](https://www.ruby-forum.com/u/casper_the_ghost)\
**Post date:** [July 27, 2007, 4:15pm UTC](https://www.ruby-forum.com/t/unit-testing-models-with-relationships-between-tables/110548/2 "2007-07-27T16:15:01Z")

</div>

removed\_email\_address@domain.invalid wrote:

> I’m quite new to Rails but even newer to the idea of unit testing as  
> all the things I have done so far have been relatively small and so I  
> haven’t bothered with unit tests. I’m just embarking on a much bigger  
> project and wanted some advice as to testing strategies.

Read everything I wrote over the past decade (including the comics) (-;

> For instance I have one model, ModelA say that belongs to another,  
> ModelB. I would like to use fixtures to preload some data; how do I  
> get the unit test for ModelA to load the fixture data for ModelB so  
> that I can perform the tests with the table dependencies in place?

In the fixtures, specify low numbers for each item’s id. Then copy the  
matching numbers into other fixtures, so model\_b\_id: 2 refers to the  
model\_bs.yml with id: 2.

(This data duplication is not DRY; this is a known issue with fixtures  
that someone might fix someday.)

> How  
> do I specify the foreign key value in the ModelA fixture so that it  
> refers to a record in ModelB?

Then put fixtures :model\_as, :model\_bs in the top of your test suite,  
and test like this:

ma = model\_as(:my\_model\_a)  
assert\_equal ‘foo’, ma.model\_b.name

That’s it. The .model\_b spontaneously populates when you call it.

> What are the strategies when it comes to testing models with  
> relationships between tables? Do you just test as if there was no  
> relationship and use dummy values for foreign key fields or should the  
> relationships also be tested?

You need tests that resist bugs when you refactor your code. (This  
makes refactoring easier, which makes your initial design less  
important!)

The best way to test is “test first”, so you write a test that fails  
because your model\_a can’t do something yet. Then you upgrade model\_a  
to pass the test. If model\_a requires a model\_b to get its job done,  
then the test will check that the job is done, and this forces model\_a  
and model\_b to have some relationship.

Done right, you won’t test the navigation itself between A and B. So  
you are free to refactor that navigation (such as a migration that  
converts has\_one to has\_many), and if the test still passes, then A  
and B still get their job done.

A test case should follow the AAA pattern:

def test\_case  
a = model\_as(:my\_a) # Assemble test targets  
q = a.perform # Activate the target method  
assert\_equal 42, q # Assert the result  
end

Most tests should call a .perform method that actually does something.  
The original rule for this was “don’t test getters and setters”. That  
means don’t test trivial methods that merely fetch data. These include  
your has\_many relationships. Only test methods that add business value  
to your app, and these methods will test the getters and setters for  
you.

> Also on a separate note, is there any point testing all the default  
> validations implemented by rails when they are themselves tested as  
> part of the rails framework?

Are you going to refactor the rails framework?

–  
Phlip  
[http://www.oreilly.com/catalog/9780596510657/](http://www.oreilly.com/catalog/9780596510657/)  
^ assert\_xpath  
[O'Reilly Media - Technology and Business Training](http://tinyurl.com/23tlu5) ← assert\_raise\_message
