Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails (显然)两个rake任务的相同测试;只有一个通过_Ruby On Rails_Rspec_Rake - Fatal编程技术网

Ruby on rails (显然)两个rake任务的相同测试;只有一个通过

Ruby on rails (显然)两个rake任务的相同测试;只有一个通过,ruby-on-rails,rspec,rake,Ruby On Rails,Rspec,Rake,我正在尝试用rspec为同一个文件中定义的两个rake任务编写测试(在rails3.0.11项目中)。由于某种原因,他们中只有一个人通过了考试。我已经写了一个小演示来抽象出任务的实际内容,同样的事情也发生了。当从命令行使用rake调用这两个任务时,这两个任务都可以工作。发生什么事?这是我的演示: lib/tasks/demo_tasks.rake namespace :demo do task :test => :environment do puts "test!" en

我正在尝试用rspec为同一个文件中定义的两个rake任务编写测试(在rails3.0.11项目中)。由于某种原因,他们中只有一个人通过了考试。我已经写了一个小演示来抽象出任务的实际内容,同样的事情也发生了。当从命令行使用
rake
调用这两个任务时,这两个任务都可以工作。发生什么事?这是我的演示:

lib/tasks/demo_tasks.rake

namespace :demo do
  task :test => :environment do
    puts "test!"
  end

  task :test_two => :environment do
    puts "second test!"
  end
end
spec/lib/tasks/demo_spec.rb

require 'spec_helper'
require 'rake'

describe "test tasks" do
  let(:rake) do
    app = Rake::Application.new
    app.options.silent = true
    app
  end

  before :each do
    Rake.application = rake
    Rake.application.rake_require 'lib/tasks/demo_tasks',
                                  [Rails.root.to_s]
    Rake::Task.define_task :environment
  end

  describe "demo:test" do
    it "runs" do
      rake["demo:test"].invoke
    end
  end

  describe "demo:test_two" do
    it "also_runs" do
      rake["demo:test_two"].invoke
    end
  end
end
test tasks
  demo:test
test!
    runs
  demo:test_two
    also_runs (FAILED - 1)

Failures:

  1) test tasks demo:test_two also_runs
     Failure/Error: rake["demo:test_two"].invoke
     RuntimeError:
       Don't know how to build task 'demo:test_two'
     # ./spec/lib/tasks/demo_spec.rb:26:in `block (3 levels) in <top (required)>'
rspec spec/lib/tasks/demo_spec.rb

require 'spec_helper'
require 'rake'

describe "test tasks" do
  let(:rake) do
    app = Rake::Application.new
    app.options.silent = true
    app
  end

  before :each do
    Rake.application = rake
    Rake.application.rake_require 'lib/tasks/demo_tasks',
                                  [Rails.root.to_s]
    Rake::Task.define_task :environment
  end

  describe "demo:test" do
    it "runs" do
      rake["demo:test"].invoke
    end
  end

  describe "demo:test_two" do
    it "also_runs" do
      rake["demo:test_two"].invoke
    end
  end
end
test tasks
  demo:test
test!
    runs
  demo:test_two
    also_runs (FAILED - 1)

Failures:

  1) test tasks demo:test_two also_runs
     Failure/Error: rake["demo:test_two"].invoke
     RuntimeError:
       Don't know how to build task 'demo:test_two'
     # ./spec/lib/tasks/demo_spec.rb:26:in `block (3 levels) in <top (required)>'
测试任务
演示:测试
测试!
跑
演示:测试二
还运行\u(失败-1)
失败:
1) 测试任务演示:测试2也运行
失败/错误:rake[“demo:test_two”]。调用
运行时错误:
不知道如何构建任务“演示:测试2”
#./spec/lib/tasks/demo_spec.rb:26:in'block(3层)in'

简而言之:
之前的
更改为
之前的所有
(而不是
:每个

或:将空数组作为第三个参数传递给
rake\u require

Rake.application.rake_require 'lib/tasks/demo_tasks', 
                              [Rails.root.to_s], 
                              []
详细信息

def rake_require(file_name, paths=$LOAD_PATH, loaded=$")
  fn = file_name + ".rake"
  return false if loaded.include?(fn)
  ...
$”
是一个Ruby特殊变量,用于保存由
require
加载的模块数组

Rake.application.rake_require 'lib/tasks/demo_tasks', 
                              [Rails.root.to_s], 
                              []
如果您不传递可选参数,
rake\u require
将使用Ruby加载的模块数组。这意味着该模块不会再次加载:Ruby知道该模块已加载,rake检查Ruby知道什么,并且它是每个测试的新rake实例

切换到
之前:所有
都有效,因为这意味着
块只运行一次:一个rake实例,一个模块加载,每个人都很高兴

总之,为什么要重新加载两次rake环境呢?您的目标是测试您的任务,这并不需要每个规范都有一个新的rake上下文

您可以完全消除本地规范,但代价是每个规范中都有一些细微的冗长:

describe "test tasks" do
  before :all do
    Rake.application = Rake::Application.new
    Rake.application.rake_require 'lib/tasks/demo_tasks', [Rails.root.to_s]
    Rake::Task.define_task :environment
  end

  describe "demo:test" do
    it "runs" do
      Rake::Task["demo:test"].invoke
    end
  end
end
您可以在
before
块中定义一个实例变量,以避免
Rake::Task
引用:

before :all do
  @rake = Rake::Application.new
  Rake.application = @rake
  Rake.application.rake_require 'lib/tasks/demo_tasks', [Rails.root.to_s]
  Rake::Task.define_task :environment
end

describe "demo:test" do
  it "runs" do
    @rake["demo:test"].invoke

在我看来,有很多原因不太可取。

一个流行的搜索引擎把我带到了这里,就像在我的例子中,当一个给定的测试多次使用
#invoke
时,我看到测试失败。下面的解决方案基于@dave newtown的答案

出现此问题的原因是,在编写时(Rake v12),
#invoke
只运行一次任务,例如:

RSpec.description“demo:test”do
它“跑”了吗
expect(SomethingWeAreInvoking).到eql(proofifwas调用)
Rake::Task[“demo:test”]。调用
结束
它“跑”了吗
expect(SomethingWeAreInvoking).到eql(proofifwas调用)
Rake::Task[“demo:test”]。调用
结束
结束
如果测试写得很好并且任务调用正确,那么它可能会通过第一个运行的任何一个
,但是第二个
it
总是会失败,就像在给定的
Rake中一样。应用程序
,使用
#invoke
只会运行一次任务。在任务内部显然记住状态之前已经运行过e
Rake.application
实例

是的,这确实意味着至少在测试的RakeV12下,很多在线文章显示了如何测试Rake任务是不正确的,或者说没有问题,因为它们在示例中只显示了对任何给定任务的单个测试

我们可以使用Rake的
#execute
,但这不会运行依赖的任务,因此会导致其自身的一组问题,并使我们更加远离测试Rake堆栈,就好像它是在命令行上调用的一样

取而代之的是,将已被接受的答案与在线的其他信息混合在一起,产生了以下替代方案:

require'spec\u helper'
需要“耙子”
RSpec.description“演示:测试”do
以前:每个人都做
Rake.application=Rake::application.new
Rake.application.Rake_需要'lib/tasks/demo_tasks',[Rails.root.to_s],]
Rake::Task.define_任务(:环境)
结束
它“跑”了吗
expect(SomethingWeAreInvoking).到eql(proofifwas调用)
Rake.application.invoke_任务('demo.test')
结束
它“使用参数”do运行
expect(SomethingWeAreInvoking).到eql(proofifwas调用)
Rake.application.invoke_任务('demo.test[42]”)
结束
结束
  • 它在每个
之前准备Rake
  • 每次都会创建一个新的
    Rake.application
    ;这意味着我们可以在任意数量的测试中使用
    invoke
    ,尽管在任何单个测试中只能使用一次
  • 如果我们只使用
    Rake.application
    开箱即用的实例,我们就可以编写
    Rake.application.Rake\u require'tasks/demo\u tasks'
    ,因为所有路径等都已设置,但由于我们肯定需要为每个测试创建一个新的Rake应用实例,以避免在测试中“弄脏”其状态,因此“长柄”“需要来自@dave newtown的表格
  • 我使用
    Rake.application.invoke_task
    而不是
    Rake::task[…]。invoke
    。这使得参数的语法与Rake命令行上使用的语法相同,我认为这是测试使用参数的任务的更“准确”和自然的方法
  • 是的,这确实意味着至少在测试的RakeV12下,许多在线文章显示了如何测试Rake任务是不正确的,或者说没有问题,因为它们在示例中只显示了对任何给定任务的单个测试。很可能早期的Rake版本没有这样做,所以这些文章在编写时是正确的

    希望有人觉得这有帮助

    参考文章:

    • -线索位于“如果需要,请调用任务”。先调用先决条件”(我的重点)
    • 比较-“执行与此任务相关的操作”,未提及“如果需要”或先决条件
    • 搜索引擎会产生诸如
    (搜索引擎提示:测试rake rspec测试调用运行在