Ruby on rails 4 我仅从小型测试的第二个循环中获得ActiveRecord::RecordNotFound

Ruby on rails 4 我仅从小型测试的第二个循环中获得ActiveRecord::RecordNotFound,ruby-on-rails-4,factory-bot,minitest,Ruby On Rails 4,Factory Bot,Minitest,我正在用RubyonRails4.2运行minitest。我暂时无法更改框架的版本。 我想测试几个地区的邮件操作。 所以我想在执行所有测试之前进行初始化,并通过FactoryBot在数据库中创建用户 我想只做一次,而不是在所有测试之前,因为它没有性能 下面是我的小型测试的类别: require 'test_helper' class PurchaseMailerTest < ActionMailer::TestCase @@flag = nil before do

我正在用RubyonRails4.2运行minitest。我暂时无法更改框架的版本。 我想测试几个地区的邮件操作。 所以我想在执行所有测试之前进行初始化,并通过FactoryBot在数据库中创建用户

我想只做一次,而不是在所有测试之前,因为它没有性能

下面是我的小型测试的类别:

require 'test_helper'


class PurchaseMailerTest < ActionMailer::TestCase

  @@flag = nil

  before do
        unless @@flag
            @@emails = Hash.new
            @@buyers = Hash.new
            @@sales = Hash.new
            I18n.available_locales.each do |locale|
                    buyer = FactoryBot.create(:buyer, sale_line_items_count: 1, locale: locale)
                    sale = buyer.orders.first.sales.first
                    email = PurchaseMailer.accepted(sale.id)
                    @@emails.store(locale, email)
                    @@buyers.store(locale, buyer)
                    @@sales.store(locale, sale)
            end
            @@flag = true
        end
  end

    I18n.available_locales.each do |locale|
            context locale do

            it 'test_email_to' do
                assert_equal [@@buyers[locale].email], @@emails[locale].to
            end

            it 'test_email_from' do
                assert_equal [ENV['EMAIL']], @@emails[locale].from
            end

            it 'test_of_subject' do
                subject_from_I18n = I18n.t('purchase_mailer.accepted.subject', sale_ref: @@sales[locale].slug, locale: locale)
                assert_includes @@emails[locale].subject, subject_from_I18n
            end
        end
    end

end
在第一个循环中,我的测试数据库包含所有初始化的数据, 在第二个循环中,数据被删除了,我不知道为什么

我认为有更优雅的解决方案,但我希望保持良好的性能,只初始化一次数据。 我已经测试了一个基于define_方法的解决方案,但问题仍然是一样的

有关更多信息,请参见我的测试助手:

ENV['RACK_ENV'] = 'test'
ENV['RAILS_ENV'] = 'test'
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest"
require "minitest/rails"
require 'factory_bot_rails'
require 'minitest-spec-context'


Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new



class ActiveSupport::TestCase
  include FactoryBot::Syntax::Methods
end

我找到了一个解决方案,首先在test_helper中创建两个方法:

ENV['RACK_ENV'] = 'test'
ENV['RAILS_ENV'] = 'test'
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest"
require "minitest/rails"
require 'factory_bot_rails'
require 'minitest-spec-context'


Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new



class ActiveSupport::TestCase
  include FactoryBot::Syntax::Methods
end
  • 开始只执行一次通过FactoryBot创建的对象,性能正常
  • 小型测试:运行数据库\u清理器后
PurchaseMailerTest类中解决方案的下一部分是在循环中使用define_方法,在名称中使用变量locale, 相反,定义测试方法的另一种样式(“it”表示rspec样式或“def”表示测试方法), 这样就不会再有ActiveRecord错误了

    I18n.available_locales.each do |locale|

            define_method :"test_mail_to_#{locale}" do 
                assert_equal [@@buyers[locale].email], @@emails[locale].to
            end
...
    I18n.available_locales.each do |locale|

            define_method :"test_mail_to_#{locale}" do 
                assert_equal [@@buyers[locale].email], @@emails[locale].to
            end
...