简体   繁体   English

如何测试Rake任务回调

[英]How to test rake task callbacks

I create test code with rspec. 我用rspec创建测试代码。 I want to test callback is executed or not. 我想测试回调是否执行。
task main: [:callback] means run callback before main , doesn't it? task main: [:callback]表示在main之前运行callback ,不是吗?

But my test failed. 但是我的测试失败了。 I looks like callback is not executed. 我好像没有执行callback Why? 为什么?

require 'rails_helper'
require 'rake'

RSpec.describe 'Rake::Task' do
  before(:all) do
    @rake = Rake::Application.new
    Rake.application = @rake
    Rake.application.rake_require('rspec_before', ["#{Rails.root}/lib/tasks"])
  end

  subject { @rake['rspec_before:main'].execute }

  it "expects run callback before main task" do
    expect{ subject }.to output(/Hello, world/).to_stdout
  end
end

My Rake task is below. 我的耙任务在下面。

namespace :rspec_before do
  task :callback do
    @greeting = "Hello, world"
  end

  # case 1
  # In this case, `callback` is NOT executed in rspec
  # In console, `callback` is executed !!!!
  desc "main task"
  task main: [:callback] do
    puts @greeting
  end

  # case 2
  # In this case, `callback` is executed in rspec
  # task :main do
  #   Rake::Task['rspec_before:callback'].execute
  #   puts @greeting
  # end
end

So, I'm not sure I would call :callback a callback , it's more of a dependency . 所以,我不确定我会叫:callback 回调 ,它更多的是依赖 A callback implies it happens after the main task is done, whereas when you do 回调意味着它在主要任务完成后发生,而在您执行时

task main: [:callback]

what you're really saying is that you depend on the other task having run first. 您真正要说的是,您依赖于首先运行的其他任务。 So I would end up changing the name of that, though that's probably just a sample/throwaway name for this question. 因此,我最终将其更改为该名称,尽管该名称可能只是该问题的样本名称。 But, I digress and I'll continue calling the task :callback as written for this answer. 但是,我离题了,我将继续按照此答案的要求调用task :callback


The main issue here is that when you call execute on a rake task, only that task gets executed. 这里的主要问题是,当您在rake任务上调用execute时,只会执行该任务。 This is because there may be situations where you don't want or need to call the entire dependency chain. 这是因为在某些情况下,您可能不需要或不需要调用整个依赖关系链。 Let's say we add another task to your file: 假设我们向您的文件添加了另一个任务:

desc "secondary task"
task :secondary do
  @greeting = 'Goodbye, Cruel World'

  Rake::Task['rspec_before:main'].execute
end

If we run this, we very likely want the main task to output Goodbye, Cruel World , instead of Hello, World and if we call all the dependencies, main would end up calling :callback which would override our @greeting and end up outputting Hello, World . 如果运行此命令,我们很可能希望main任务输出Goodbye, Cruel World ,而不是Hello, World ,如果调用所有依赖项, main最终将调用:callback ,它将覆盖我们的@greeting并最终输出Hello, World

There is, however, another task that does call the entire dependency chain: invoke : 但是,还有另一个任务会调用整个依赖项链: invoke

desc "secondary task"
task :secondary do
  @greeting = 'Goodbye, Cruel World'
  Rake::Task['rspec_before:main'].invoke
end

if we run this task, now we'll see Hello, World instead of Goodbye, Cruel World . 如果运行此任务,现在将看到Hello, World而不是Goodbye, Cruel World So, having said all of this, what does that mean for your RSpec test? 那么,说完所有这些之后,这对您的RSpec测试意味着什么? You simply need to change your subject to: 您只需要将subject更改为:

subject { @rake['rspec_before:main'].invoke }

because you are wanting to run the dependencies. 因为您要运行依赖项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM