Rails :memory: testing in SqLite
I wanted to get that nifty :memory: db thing working for the test database in Rails. There are a sparse few articles floating around telling you how to do this. All of them, IMHO, are kinda ugly, or at least not-so-elegant. Here’s my answer, which took a lot of digging around in the inner workings of rails to come by.
First, do what everyone else tells you, put this in your config/database.yml:
<pre>
test:
adapter: sqlite3
database: ":memory:"
</pre>
Once you got that, you have to have some way of loading the schema into your memory db every time you run the test. I found that the best place to do this is in config/environments/test.rb. If you have an even better place, please let me know.
At first I thought I could just load "#{RAILS_ROOT}/db/schema.rb" and be done with it. Alas, at this point there is no established connection to the db. So we have to modify things in such a way that this cute little command will get run just after establishing the db connection, but before the db is accessed. I did it like so:
<pre>
module Rails
class Initializer
alias initialize_database_old initialize_database
def initialize_database
initialize_database_old
load "#{RAILS_ROOT}/db/schema.rb"
end
end
end
</pre>
Then don’t forget to rake db:schema:dump before running rake test.
There’s probably other things you could do, like use ActiveRecord::Base.establish_connection instead of Initializer.initialize_database.
I break the above code block into lib/memdb.rb and simply require that inside of config/environments/test.rb. I tried to just add a metaclass to the config variable you see in test.rb but that is apparently some kind of impostor, because it didn’t work. Anyway, armed with this knowledge someone could probably make a pretty sane plugin to cleanly bring you :memory: testing.
Post a comment
Website and email are optional. Email will be displayeduser at example dot com.