How to Use DataMapper With Rails: Part 2
In Part I, I showed how to configure Rails to use DataMapper instead of ActiveRecord. Well, after some thought, I realized we couldn’t really test anything. Here’s the proof:
1 class ArticleTest < ActiveSupport::TestCase 2 def test_database_is_empty 3 assert Article.all.empty? 4 end 5 end
Running the tests results in a failure:
1 $ rake test:units 2 (in /Users/francois/Documents/work/dm_on_rails) 3 /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -Ilib:test "/Library/Ruby/Gems/1.8/gems/rake-0.8.2/lib/rake/rake_test_loader.rb" "test/unit/article_test.rb" 4 Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.8.2/lib/rake/rake_test_loader 5 Started 6 .F 7 Finished in 0.049976 seconds. 8 9 1) Failure: 10 test_database_is_empty(ArticleTest) 11 [./test/unit/article_test.rb:10:in `test_db_empty_on_start' 12 /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/testing/setup_and_teardown.rb:67:in `__send__' 13 /Library/Ruby/Gems/1.8/gems/activesupport-2.1.0/lib/active_support/testing/setup_and_teardown.rb:67:in `run']: 14 <false> is not true. 15 16 2 tests, 2 assertions, 1 failures, 0 errors 17 rake aborted! 18 Command failed with status (1): [/System/Library/Frameworks/Ruby.framework/...] 19 20 (See full trace by running task with --trace)
Time to open the wonderful world of transactions! At the time of this writing, DataMapper is at 0.9.6. There is a comment in lib/dm-core/transaction.rb saying TODO: move to dm-more/dm-transactions
. If the code below doesn’t work, add a new dependency on dm-transaction.
So, let’s begin by adding new setup / teardown hooks to Test::Unit::TestCase:
test/test_helper.rb
1 class Test::Unit::TestCase 2 setup do 3 @__transaction = DataMapper::Transaction.new(DataMapper.repository(:default)) 4 @__transaction.begin 5 6 # FIXME: Should I really be calling #push_transaction like that, or is there a better way? 7 DataMapper.repository(:default).adapter.push_transaction(@__transaction) 8 end 9 10 teardown do 11 if @__transaction 12 DataMapper.repository(:default).adapter.pop_transaction 13 @__transaction.rollback 14 @__transaction = nil 15 end 16 end 17 end
- GitHub commit: Handle transactions during testing to allow each test to be independent of the other ones
With that code in place, we can run the tests again and see the results of our hard work:
1 $ rake test:units 2 (in /Users/francois/Documents/work/dm_on_rails) 3 /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -Ilib:test "/Library/Ruby/Gems/1.8/gems/rake-0.8.2/lib/rake/rake_test_loader.rb" "test/unit/article_test.rb" 4 Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.8.2/lib/rake/rake_test_loader 5 Started 6 .. 7 Finished in 0.009485 seconds. 8 9 2 tests, 2 assertions, 0 failures, 0 errors