在运行我编写的迁移之后,我想测试某些条件是否成立。目前最好的方法是什么?
具体来说:我进行了一次迁移,向模型中添加了一列,并为其提供了默认值。但是我忘记了更新该模型的所有预先存在的实例,使其具有新列的默认值。我现有的测试都不能捕捉到这一点,因为它们都从一个新的数据库开始,并添加新的数据,这将是默认的。但如果我推动生产,我知道事情会崩溃,我希望我的测试能告诉我这一点。
我找到了http://spin.atomicobject.com/2007/02/27/migration-testing-in-rails/,但还没试过。它很古老了。这是最先进的吗?
发布于 2012-04-14 16:26:42
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
之前,像迁移之前一样设置一些数据,并断言它的状态是您在迁移后所期望的。我希望这能帮到你。
更新:自从发布了这篇文章后,我在我的博客上发布了一个example migration test。
更新:这是一个测试迁移的想法,即使迁移已经在开发中运行。
编辑:我已经使用我的博客文章中的人为示例将我的概念验证更新为一个完整的规范文件。
# 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
发布于 2017-05-16 21:09:54
我只需创建该类的一个实例,然后对其调用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
发布于 2011-05-23 16:27:31
我进行了一次迁移,向模型中添加了一列,并为其提供了默认值。但是我忘记了更新该模型的所有预先存在的实例,使其具有新列的默认值。
基于这句话,你只是想测试一个“旧的”模型,有缺省的,对吗?
从理论上讲,您正在测试rails是否正常工作。也就是说,“rails是否为新添加的列设置了默认值”
添加列和设置默认值将存在于数据库的“旧”记录中。
因此,您不需要更新其他记录来反映默认设置。理论上没有什么需要测试的,因为rails已经为您测试过了。最后,使用默认值的原因是,您不必更新以前的实例即可使用该默认值,对吧?
https://stackoverflow.com/questions/6079016
复制相似问题