Path: | README |
Last Update: | Wed Feb 20 01:30:13 -0500 2008 |
NullDB is the Null Object pattern as applied to ActiveRecord database adapters. It is a database backend that translates database interactions into no-ops. Using NullDB enables you to test your model business logic - including after_save hooks - without ever touching a real database.
Once installed, NullDB can be used much like any other ActiveRecord database adapter:
ActiveRecord::Base.establish_connection :adapter => :nulldb
NullDB needs to know where you keep your schema file in order to reflect table metadata. By default it looks in RAILS_ROOT/db/schema.rb. You can override that by setting the schema option:
ActiveRecord::Base.establish_connection :adapter => :nulldb, :schema => foo/myschema.rb
NullDB comes with RSpec integration. To replace the database with NullDB in all of your specs, put the following in your spec/spec_helper:
require 'nulldb_rspec' include NullDB::RSpec::NullifiedDatabase
Or if you just want to use NullDB in a specific spec context, you can include the same module inside a context:
require 'nulldb_rspec' describe Employee, "with access to the database" do fixtures :employees # ... end describe Employee, "with NullDB" do include NullDB::RSpec::NullifiedDatabase # ... end
NullDB::Rspec provides some custom matcher support for verifying expectations about interactions with the database:
describe Employee do include NullDB::RSpec::NullifiedDatabase it "should cause an insert statement to be executed" do Employee.create! Employee.connection.should have_executed(:insert) end end
UnitRecord-style verification that no database calls have been made at all can be achieved by using the special +:anything+ symbol:
describe "stuff that shouldn't touch the database" do after :each do Employee.connection.should_not have_executed(:anything) end # ... end
You can also experiment with putting NullDB in your database.yml:
unit_test: adapter: nulldb
However, due to the way Rails hard-codes specific database adapters into its standard Rake tasks, you may find that this generates unexpected and difficult-to-debug behavior. Workarounds for this are under development.
There are a number of advantages to writing unit tests that never touch the database. The biggest is probably speed of execution - unit tests must be fast for test-driven development to be practical. Another is separation of concerns: unit tests should be exercising only the business logic contained in your models, not ActiveRecord. For more on why testing-sans-database is a god idea, see: www.dcmanges.com/blog/rails-unit-record-test-without-the-database.
NullDB is one way to separate your unit tests from the database. It was inspired by the ARBS and UnitRecord libraries. It differs from them in a couple of ways:
One concrete advantage of this null-object pattern design is that it is possible with NullDB to test after_save hooks. With NullDB, you can call +save+ and all of the usual callbacks will be called - but nothing will be saved.
NullDB was written by Avdi Grimm <avdi@avdi.org>
* Version 0.0.1 (2007-02-18) - Initial Release
See the LICENSE file for licensing information.