XZV*_*SFD 56 database testing ruby-on-rails
我想在运行我写过的迁移后测试某些条件是否成立.目前最好的方法是什么?
为了使这个具体:我进行了一次迁移,为模型添加了一个列,并给它一个默认值.但是我忘记更新该模型的所有预先存在的实例以获得新列的默认值.我现有的测试都没有捕获到它,因为它们都是从一个新数据库开始并添加新数据,这些数据将具有默认值.但如果我投入生产,我知道事情会破裂,我希望我的测试告诉我.
我找到了http://spin.atomicobject.com/2007/02/27/migration-testing-in-rails/,但还没试过.它很老了.这是最先进的吗?
Ami*_*tin 19
Peter Marklund在这里有一个测试迁移的例子:https://gist.github.com/700194(在rspec中).
注意,自他的示例以来,迁移已更改为使用实例方法而不是类方法.
这是一个总结:
test/unit/import_legacy_devices_migration_test.rb
或者spec/migrations/import_legacy_devices_migration_spec.rb
注意:您可能需要显式加载迁移文件,因为rails可能不会为您加载它.这样的事情应该做:require File.join(Rails.root, 'db', 'migrate', '20101110154036_import_legacy_devices')
up
和down
方法.如果你的逻辑很复杂,我建议将一些逻辑重构为更容易测试的小方法.up
,设置一些在迁移之前的数据,并声明它的状态是您之后所期望的.我希望这有帮助.
更新:自发布此消息后,我在我的博客上发布了一个示例迁移测试.
更新:这是一个测试迁移的想法,即使它们已经在开发中运行.
编辑:我已经使用我博客文章中的人为设计示例将我的概念验证更新为完整的spec文件.
# spec/migrations/add_email_at_utc_hour_to_users_spec.rb
require 'spec_helper'
migration_file_name = Dir[Rails.root.join('db/migrate/*_add_email_at_utc_hour_to_users.rb')].first
require migration_file_name
describe AddEmailAtUtcHourToUsers do
# This is clearly not very safe or pretty code, and there may be a
# rails api that handles this. I am just going for a proof of concept here.
def migration_has_been_run?(version)
table_name = ActiveRecord::Migrator.schema_migrations_table_name
query = "SELECT version FROM %s WHERE version = '%s'" % [table_name, version]
ActiveRecord::Base.connection.execute(query).any?
end
let(:migration) { AddEmailAtUtcHourToUsers.new }
before do
# You could hard-code the migration number, or find it from the filename...
if migration_has_been_run?('20120425063641')
# If this migration has already been in our current database, run down first
migration.down
end
end
describe '#up' do
before { migration.up; User.reset_column_information }
it 'adds the email_at_utc_hour column' do
User.columns_hash.should have_key('email_at_utc_hour')
end
end
end
Run Code Online (Sandbox Code Playgroud)
我只是创建该类的实例,然后在其上调用up
或down
对其进行调用。
例如:
require Rails.root.join(
'db',
'migrate',
'20170516191414_create_identities_ad_accounts_from_ad_account_identity'
)
describe CreateIdentitiesAdAccountsFromAdAccountIdentity do
subject(:migration) { described_class.new }
it 'properly creates identities_ad_accounts from ad account identities' do
create_list :ad_account, 3, identity_id: create(:identity).id
expect { suppress_output { migration.up } }
.to change { IdentitiesAdAccount.count }.from(0).to(3)
end
end
Run Code Online (Sandbox Code Playgroud)
我进行了迁移,将一列添加到模型中,并为其指定默认值。但我忘记更新该模型的所有预先存在的实例,以便为新列提供默认值。
根据这个声明,您只是想测试“旧”模型是否具有默认值,对吗?
理论上,您正在测试 Rails 是否有效。即,“rails 是否为新添加的列设置默认值”
添加列并设置默认值将存在于数据库的“旧”记录中。
因此,您不需要更新其他记录来反映默认设置。理论上没有什么可以测试的,因为 Rails 已经为你测试过了。最后,使用默认值的原因是您不必更新以前的实例即可使用该默认值,对吧?
归档时间: |
|
查看次数: |
10039 次 |
最近记录: |