为什么我的rake任务在我的测试中运行了两次?

Cam*_*rzt 6 rake ruby-on-rails minitest rake-task

我有一个rake任务测试,我按照我在网上找到的唯一例子进行设置.

它看起来像这样:

require 'test_helper'
require 'minitest/mock'
require 'rake'

class TestScrapeWelcome < ActiveSupport::TestCase
  def setup
    Rake.application.init
    Rake.application.load_rakefile

    @task = Rake::Task['scrape:scrape']
    @task.reenable
  end

  def teardown
    Rake::Task.clear
  end

  test "scraping text and sending to elasticsearch" do
    mocked_client = Minitest::Mock.new
    get_fixtures.each_with_index do |arg,i|
      mocked_client.expect :index, :return_value, [index: "test", type: 'welcome', id: i, body: arg]
    end
    Elasticsearch::Model.stub :client, mocked_client do
      @task.invoke
    end
    assert mocked_client.verify
  end

  private

  def get_fixtures
    (0..11).map { |i|
      File.read("test/fixtures/scrape/index_#{i}.json")
    }
  end

end
Run Code Online (Sandbox Code Playgroud)

但是一旦任务开始运行,它再次开始运行而没有我做任何事情(puts@task.invoke显示之前和之后打印任务只运行一次).

Cam*_*rzt 12

事实证明,在测试运行时已经需要并初始化rake,因此需要删除以下所有行,或者将任务定义两次并运行两次,即使您只调用一次.

require 'minitest/mock'
require 'rake'
...
Rake.application.init
Rake.application.load_rakefile
Run Code Online (Sandbox Code Playgroud)


ihe*_*gie 5

rails 5.1 的更新答案(使用 minitest):

我发现我需要以下内容来一次性加载任务:

MyAppName::Application.load_tasks if Rake::Task.tasks.empty?
Run Code Online (Sandbox Code Playgroud)

或者MyAppName::Application.load_tasks,如果您不介意加载任务,即使在运行不需要它们的单个测试时,也可以添加到您的 test_helper。

(将 MyAppName 替换为您的应用程序名称)