在 Rails 4 中测试我的 Rake 任务丢失了一个实例变量
Testing my Rake task in Rails 4 loses an instance variable
我无法通过我的 Rake 任务测试;似乎在 rake 任务 运行 之后我失去了我的实例变量,因为它 returns nil 而在 Rake 任务是 运行 之前我得到了一个记录
所以在我所有的测试之前我有这个配置设置
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require 'rake'
load File.expand_path('../../lib/tasks/create_events.rake', __FILE__)
load File.expand_path('../../lib/tasks/update_event.rake', __FILE__)
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean_with :truncation
Rake::Task.define_task(:environment)
Rake::Task['create_events:create_event_data'].invoke
end
config.after(:suite) do
DatabaseCleaner.clean
end
end
我的规格文件是这样设置的
require "rails_helper"
require 'rake'
RSpec.describe "update_event:next_event_date Rake Task" do
it "should change the next occurrence date" do
@update_event = Event.where(next_occurrence: Date.today)
# So here @update_event returns 1 record (Active Record Relation)
Rake::Task.define_task(:environment)
Rake::Task['update_event:next_event_date'].invoke
# By here @update_event = nil (Active Record Relation = [])
case @update_event.first.weekly_frequency
when 1
expect(@update_event.first.next_occurrence).to eq(Date.today + 7.days)
when 2
expect(@update_event.first.next_occurrence).to eq(Date.today + 14.days)
when 6
expect(@update_event.first.next_occurrence).to eq(Date.today + 42.days)
end
end
end
这背后的原因是什么?我该如何正确测试?
我实际的 Rake 任务是这样的
namespace :update_event do
desc "Update next_occurrence date for an event"
task next_event_date: :environment do
@event = Event.where(next_occurrence: Date.today)
@event.each do |e|
if e.weekly_frequency == 1
e.update_attributes next_occurrence: Date.today + 7.days
elsif e.weekly_frequency == 2
e.update_attributes next_occurrence: Date.today + 14.days
elsif e.weekly_frequency == 6
e.update_attributes next_occurrence: Date.today + 42.days
end
end
end
end
编辑
所以我稍微修改了我的规格
require "rails_helper"
require 'rake'
RSpec.describe "update_event:next_event_date Rake Task" do
it "should change the next occurrence date" do
@update_event = Event.where(next_occurrence: Date.today)
event_id = Event.find(@update_event.first.id)
Rake::Task.define_task(:environment)
Rake::Task['update_event:next_event_date'].invoke
@after_update = Event.find(event_id)
case @after_update.weekly_frequency
when 1
expect(@after_update.next_occurrence).to eq(Date.today + 7.days)
when 2
expect(@after_update.next_occurrence).to eq(Date.today + 14.days)
when 6
expect(@after_update.next_occurrence).to eq(Date.today + 42.days)
end
end
end
这通过了,但我不确定为什么我丢失了我的第一个实例变量。
您不是 "losing" 您的实例变量。您的实例变量是一个查询,它将在您的 rake 任务之前和之后产生不同的结果。您修改后的测试在 rake 任务之前执行查询,并将从结果派生的内容保存在局部变量中(即第一条记录的 ID)。您可以通过如下方式保存事件来达到类似的效果:
@update_event = Event.find_by(next_occurrence: Date.today)
因为 find_by
returns ActiveRecord
而不是 ActiveRelation
。
我无法通过我的 Rake 任务测试;似乎在 rake 任务 运行 之后我失去了我的实例变量,因为它 returns nil 而在 Rake 任务是 运行 之前我得到了一个记录
所以在我所有的测试之前我有这个配置设置
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require 'rake'
load File.expand_path('../../lib/tasks/create_events.rake', __FILE__)
load File.expand_path('../../lib/tasks/update_event.rake', __FILE__)
require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean_with :truncation
Rake::Task.define_task(:environment)
Rake::Task['create_events:create_event_data'].invoke
end
config.after(:suite) do
DatabaseCleaner.clean
end
end
我的规格文件是这样设置的
require "rails_helper"
require 'rake'
RSpec.describe "update_event:next_event_date Rake Task" do
it "should change the next occurrence date" do
@update_event = Event.where(next_occurrence: Date.today)
# So here @update_event returns 1 record (Active Record Relation)
Rake::Task.define_task(:environment)
Rake::Task['update_event:next_event_date'].invoke
# By here @update_event = nil (Active Record Relation = [])
case @update_event.first.weekly_frequency
when 1
expect(@update_event.first.next_occurrence).to eq(Date.today + 7.days)
when 2
expect(@update_event.first.next_occurrence).to eq(Date.today + 14.days)
when 6
expect(@update_event.first.next_occurrence).to eq(Date.today + 42.days)
end
end
end
这背后的原因是什么?我该如何正确测试?
我实际的 Rake 任务是这样的
namespace :update_event do
desc "Update next_occurrence date for an event"
task next_event_date: :environment do
@event = Event.where(next_occurrence: Date.today)
@event.each do |e|
if e.weekly_frequency == 1
e.update_attributes next_occurrence: Date.today + 7.days
elsif e.weekly_frequency == 2
e.update_attributes next_occurrence: Date.today + 14.days
elsif e.weekly_frequency == 6
e.update_attributes next_occurrence: Date.today + 42.days
end
end
end
end
编辑
所以我稍微修改了我的规格
require "rails_helper"
require 'rake'
RSpec.describe "update_event:next_event_date Rake Task" do
it "should change the next occurrence date" do
@update_event = Event.where(next_occurrence: Date.today)
event_id = Event.find(@update_event.first.id)
Rake::Task.define_task(:environment)
Rake::Task['update_event:next_event_date'].invoke
@after_update = Event.find(event_id)
case @after_update.weekly_frequency
when 1
expect(@after_update.next_occurrence).to eq(Date.today + 7.days)
when 2
expect(@after_update.next_occurrence).to eq(Date.today + 14.days)
when 6
expect(@after_update.next_occurrence).to eq(Date.today + 42.days)
end
end
end
这通过了,但我不确定为什么我丢失了我的第一个实例变量。
您不是 "losing" 您的实例变量。您的实例变量是一个查询,它将在您的 rake 任务之前和之后产生不同的结果。您修改后的测试在 rake 任务之前执行查询,并将从结果派生的内容保存在局部变量中(即第一条记录的 ID)。您可以通过如下方式保存事件来达到类似的效果:
@update_event = Event.find_by(next_occurrence: Date.today)
因为 find_by
returns ActiveRecord
而不是 ActiveRelation
。