Ruby on rails 如何测试由“执行”执行的行为;“什么时候?”;

Ruby on rails 如何测试由“执行”执行的行为;“什么时候?”;,ruby-on-rails,ruby,rspec,cron,whenever,Ruby On Rails,Ruby,Rspec,Cron,Whenever,我使用where在Rails中调度任务,我想找到一种方法来测试正在执行的行为 有没有办法在测试中触发事件(比如RSpec),这样我就可以对结果做出断言?执行的任务本身就是一个类方法,因为我已经在Rails控制台中手动测试了它,但是是否有方法触发事件,以便发生这种行为,并且我可以断言它在config/schedule.rb中以相同的方式工作?where event 与常规spec运行相比,where wrapps(即cron)中唯一发生变化的是系统环境,更具体地说是环境变量 无论何时,只要使用cr

我使用where在Rails中调度任务,我想找到一种方法来测试正在执行的行为

有没有办法在测试中触发事件(比如RSpec),这样我就可以对结果做出断言?执行的任务本身就是一个类方法,因为我已经在Rails控制台中手动测试了它,但是是否有方法触发事件,以便发生这种行为,并且我可以断言它在config/schedule.rb中以相同的方式工作?

where event 与常规spec运行相比,where wrapps(即cron)中唯一发生变化的是系统环境,更具体地说是环境变量

无论何时,只要使用cron的可执行文件在cron中安装,您都可以看到这些命令:

$ whenever
Cron总是从原始环境开始。如果您检查crontab内容(使用
crontab-e
),您将看到设置的顶级变量。您可以在此处设置其他变量。例如:

SHELL="/bin/bash"
PATH="/sbin:/bin:/usr/sbin:/usr/bin"
MAILTO="your_user"                                                                                                                       
HOME="/home/your_user"
RAILS_ENV="production"
不过,您不应该需要这些,因为只要使用了一个很好的技巧:它使用
/bin/bash-l-c
调用所有命令。这确保它使用一个登录shell,加载
~/.bashrc
文件。因此,在您的bashrc文件中导出的任何变量都可以在cron执行中访问

还请注意,一些发行版(如gentoo)在skel bashrc文件中有一个检查,如果shell不是交互式的,则该检查将退出(因此,如果在cron中需要环境变量,则必须先设置环境变量)

使用类似环境的测试 要回答关于测试的问题,这可能不是一个好主意。这里没有与您的代码库相关的内容,只与您的系统相关(类似地,您不会测试您的系统在您的规范中安装了哪个版本的postgres或imagemagick)

为了调试,您可以在调用rspec时模拟cron中发生的情况,例如:

env - HOME=/home/<your_user>/ /bin/bash -l -c 'rspec spec/'
env-HOME=/HOME///bin/bash-l-c'rspec spec/'

这将确保环境被清空(
env-
),然后将HOME设置为最小的env,然后像命令一样调用登录shell。

我使用了一个简单的技巧来声明我的期望,如下所示

require 'spec_helper'
require 'whenever'

describe 'Schedule' do
  it 'sends email 10th of each month before 08 AM EST' do
    expected = "0 7 10 * * /bin/bash -l -c 'cd  && script/rails runner -e production '\\''Delayed::Job.enqueue(MyMailerJob.new([2,3,4]), priority: 10)'"
    expect(cron_output).to include(expected)
  end
end


def cron_output
  Whenever::JobList.new(file: Rails.root.join("config", "schedule.rb").to_s).
                    generate_cron_output.
                    gsub(Dir.pwd, '')
end