ruby-on-rails - 如何测试 Rails 迁移?

标签 ruby-on-rails database testing

我想测试在运行我编写的迁移后某些条件是否成立。目前最好的方法是什么?

具体来说:我进行了一个迁移,将一列添加到模型中,并为其提供默认值。但是我忘记更新该模型的所有预先存在的实例以具有新列的默认值。我现有的测试都不会捕捉到这一点,因为它们都是从一个新的数据库开始并添加新数据,这些数据将具有默认值。但如果我插入生产,我知道事情会失败,我希望我的测试能告诉我这一点。

我找到了 http://spin.atomicobject.com/2007/02/27/migration-testing-in-rails/ ,但没试过。它很旧了。这是最先进的吗?

最佳答案

Peter Marklund这里有一个测试迁移的示例要点:https://gist.github.com/700194 (在 rspec 中)。

请注意,自从他使用实例方法而不是类方法的示例以来,迁移已经发生了变化。

总结如下:

  1. 照常创建迁移
  2. 创建一个文件以放入迁移测试。建议:test/unit/import_legacy_devices_migration_test.rbspec/migrations/import_legacy_devices_migration_spec.rb 注意:您可能需要显式加载迁移文件,因为 rails 可能不会为您加载它。应该这样做:require File.join(Rails.root, 'db', 'migrate', '20101110154036_import_legacy_devices')
  3. 迁移(就像 ruby​​ 中的所有内容一样)只是一个类。测试 updown 方法。如果您的逻辑很复杂,我建议将部分逻辑重构为更易于测试的更小方法。
  4. 在调用 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

关于ruby-on-rails - 如何测试 Rails 迁移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6079016/

相关文章:

ruby-on-rails - 测试之间的 Rails 清理数据库不起作用

ruby-on-rails - 如何在 I18n Devise Flash 消息上使用资源属性

ruby-on-rails - 关于使用 Ruby on Rails 的 HTTPS 连接的建议

sql - 表上的额外列与磁盘上的大小

ruby-on-rails - 我如何处理两个具有不同 Ruby/Rails 版本的应用程序?

mysql - 删除旧行 MySQL 触发器 - 初学者

javascript - 如何在 PHP 中 print_r 一个 MongoDB 集合?

angular - 找不到模块 '@angular/cdk/testing'

php - 如何测试由对 php 的多个 ajax 请求创建的竞争条件?

Android 检测测试在测试使用 RoomDatabase.withTransaction 的挂起函数时卡住