Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should rails units tests hit database or not?

I have been writing tests for my rails application. I use TestUnit for unit as well as functional tests. And I use cucumber for GUI testing as well.

But I find that http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database says that it is better for unit tests not to hit the database.

I do agree that hitting database takes considerable time. I already use spork to reduce environment loading.

What is the best practice when it comes to testing a rails app?

like image 300
user Avatar asked Nov 28 '22 12:11

user


1 Answers

This is one of the cases where you shouldn't get too hung up on names. Rails refers to tests that exercise the ActiveRecord models as "unit" tests, largely because they're the lowest level tests directly supported by the framework. According to testing lore, to which I'll admit I tend to cleave fairly consistently, unit tests should have no dependencies external to the unit under test; this means things like persistence mechanisms, i.e. the database.

That said, testing ActiveRecord models of any complexity without the database will quickly make you want to eat your hands. Rails assumes that you use the database for tests; that's simply the way the framework is written. You can try to stub everything out, but you'll eventually fail since you'll end up messing around in the internals of ActiveRecord associations (not for the faint of heart). You can try to extract all of the non-persistence-related code into separate modules that test without the database, but you'll be creating quite a lot of unnecessary complexity.

Don't try to fight the framework. ActiveRecord and ActionController have very specific patterns of expected use, both in production and in tests. Rails, after all, is all about convention. If you follow the pattern of use you will do much less work, and become much less frustrated, than if you fight the conventions in order to stick with unit testing ideals. If it makes you feel better, consider your ActiveRecord tests to be "model" tests, and your functional tests to be "controller" tests (this is the terminology that rspec uses, incidentally).

All that said, you shouldn't access the database unnecessarily in your model tests (or specs). Some validations, such as uniqueness, require the database, but most do not. Many actions related to create/save callbacks and associations require the database, but others do not. Be aware of what the actions you're invoking are doing.

like image 193
Adam Milligan Avatar answered Nov 30 '22 01:11

Adam Milligan