How would go about writing proper unit testing (and integration testing for that matter) using MongoDB through Mongoid on Rails ?
I am asking, because to the opposite of using let's say SQLite3, even when running tests, everything I do does persists. So for the moment I am writing the creation test and then I manually delete everything I do. But it's getting annoying and even complicated to do for integration testing.
Sample of what I do:
before(:each) do
@user = User.create!(@attr)
end
after(:each) do
# MongoDB is not a transactional DB, so added objects (create) during tests can't be rollbacked
# checking for the existance of a similar object with exact :name and :email (regex make it case insensitive)
cleanup = User.where(:name => "Example User", :email => /^user@example.com/i)
cleanup.destroy unless cleanup.nil?
end
Any idea how to make MongoDB not persistent during Testing ? (I can't even run the console in sandbox mode because to use Mongoid I had to deactivate Active Record).
There's no way to make MongoDB non-persistent. You simply have to delete data before or after each test. There's some documentation on that here:
http://www.mongodb.org/display/DOCS/Rails+-+Getting+Started#Rails-GettingStarted-Testing
Ok thanks to Kyle who pointed me in the right direction, I found out how to make it work.
So basically the trick is to drop all your collections in mongodb for each test case that you will run. This is a bit radical, but it works. But keep in mind that you won't retain any data at all in you test db.
Finally I found that link: http://adventuresincoding.com/2010/07/how-to-configure-cucumber-and-rspec-to-work-with-mongoid
And basically what you need to do is simple:
add a block in you spec_helper.rb:
RSpec.configure do |config|
# blabla other confs
config.before :each do
Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
end
# blabla other confs
end
For Mongoid 3:
Mongoid.default_session.collections.select {|c| c.name !~ /system/ }.each(&:drop
This effectively kills all the collection within the db allowing you to run your tests fresh every time.
Alex
Another way is to use database_cleaner. It supports multiple ORMs, so I think you could do something like this:
# spec/support/database_cleaner.rb
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner[:mongoid].strategy = :truncation
DatabaseCleaner[:mongoid].clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
Here's what I did (using Test::Unit and Mongoid 3)...
# test/test_helper.rb
setup {
Mongoid.default_session.collections.select {|c| c.name !~ /system/ }.each(&:drop)
}
This one worked for me.
In spec_helper.rb
, under RSpec.configure do |config|
I put:
config.before :each do
Mongoid.purge!
end
Reference.