One problem with the
add_symbolic_names
code posted earlier on the blog is the need to keep the test fixtures in sync with the data in the production database — otherwise, code can reference constants that exist in production, and will break while running tests.
Keeping these in sync is annoying enough that I wrote a rake task to dump the contents of a table to the appropriate fixtures file. I ended up with something like this:
desc "Overwrite a fixture file with the contents of a table (set by TABLE=)"
task :generate_from_table do
ActiveRecord::Base.establish_connection(RAILS_ENV)
table_name = ENV['TABLE']
File.open("test/fixtures/#{table_name}.yml", 'w') do |file|
data = ActiveRecord::Base.connection.select_all("SELECT * FROM #{table_name}")
rows = {}
data.each do |record|
rows["#{table_name}_#{record['id']}"] = record
end
file.write rows.to_yaml
end
end
Running this rake task will generate a fixture file containing all the information in the table specified by the environment variable
TABLE
. In the future, we’ll probably look at automating the fixture generation for these symbolic tables so we don’t have to worry about failing tests when we add new rows.
UPDATE: I realized that in most cases, the symbolic name of the database row makes a much better fixture title than the id, which results in the following code:
desc "Overwrite a fixture file with the contents of a table (set by TABLE=)"
task :generate_from_table do
ActiveRecord::Base.establish_connection(RAILS_ENV)
table_name = ENV['TABLE']
File.open("test/fixtures/#{table_name}.yml", 'w') do |file|
data = ActiveRecord::Base.connection.select_all("SELECT * FROM #{table_name}")
rows = {}
data.each do |record|
fixture_name = record['symbolic_name'].blank? ?
"#{table_name}_#{record['id']}" :
record['symbolic_name'].downcase
rows[fixture_name] = record
end
file.write rows.to_yaml
end
end
This gives us nice fixtures that look like this:
---
dog:
name: Dog
id: "1"
symbolic_name: DOG
cat:
name: Cat
id: "2"
symbolic_name: CAT
No comments:
Post a Comment