0

我一直在争论为什么当我的规范通过 pry 测试正常工作时,Simplecov 没有报告这个 Rake 任务。谁能指出我正确的方向?

以下 rake 任务...

namespace :myapp do
  namespace :data do
    namespace :load do
      desc 'Enqueue a range of dates by provider'
      task range: :environment do
        cli = HighLine.new
        msg('Select the dates for your data pull. Format: yyyy-mm-dd')
        created_before = cli.ask('Data created_before? ', Date)
        created_after = cli.ask('Data created_after? ', Date)
        if created_after >= created_before
          error_msg('The created_after date must be less than created_before!')
          exit
        else
          Resque.enqueue(AmazonMws::ImportOrdersJob, created_before: created_before, created_after: created_after)
        end
      end

      desc 'Enqueue from a specified date by provider'
      task from: :environment do
        cli = HighLine.new
        msg('Select the date for your data pull. Format: yyyy-mm-dd')
        created_from = cli.ask('Data created_from? ', Date)
        Resque.enqueue(AmazonMws::ImportOrdersJob, created_from: created_from)
      end
    end
  end
end

以下规格...

describe 'rake task myapp:data:load:from' do
  include_context 'rake'
  let(:task_path) { 'tasks/data.rake' }

  before do
    ResqueSpec.reset!
  end

  describe ':range' do
    let(:created_before) { '2017-01-02' }
    let(:created_after) { '2017-01-01' }
    let(:task_name) { 'myapp:data:load:range' }
    before do
      invoke_task.reenable
      allow(highline).to receive(:ask).with('Data created_before? ', Date).and_return(created_before)
    end

    it 'exits if created_after is not >= created_before' do
      allow(highline).to receive(:ask).with('Data created_after? ', Date).and_return(created_before)
      expect { invoke_task.invoke }.to raise_error(SystemExit)
    end

    # rubocop:disable RSpec/MultipleExpectations
    it 'exits with the right message' do
      allow(highline).to receive(:ask).with('Data created_after? ', Date).and_return(created_before)

      expect do
        expect { invoke_task.invoke }.to output('The created_after date must be less than created_before!').to_stdout
      end.to raise_error(SystemExit)
    end
    # rubocop:enable all

    it 'processes from a specified starting point' do
      allow(highline).to receive(:ask).with('Data created_after? ', Date).and_return(created_after)
      invoke_task.invoke
      expect(AmazonMws::ImportOrdersJob).to have_queue_size_of(1)
    end
  end

  describe ':from' do
    let(:created_from) { '2017-01-01' }
    let(:task_name) { 'myapp:data:load:from' }
    before do
      invoke_task.reenable
      allow(highline).to receive(:ask).and_return(created_from)
    end

    it 'processes from a specified starting point' do
      # expect(Resque).to receive(:enqueue).with(AmazonMws::ImportOrdersJob, created_from: created_from)
      invoke_task.invoke
      expect(AmazonMws::ImportOrdersJob).to have_queue_size_of(1)
    end
  end
end

rake 任务的共享上下文...

shared_context 'rake' do
  let(:invoke_task) { rake[task_name] }
  let(:highline) { instance_double(HighLine) }
  let(:rake) { Rake::Application.new }

  before do
    Rake.application = rake
    load File.expand_path("#{Rails.root}/lib/#{task_path}", __FILE__)
    Rake::Task.define_task(:environment)
    allow(HighLine).to receive(:new).and_return(highline)
    # rubocop:disable all
    allow_any_instance_of(Object).to receive(:msg).and_return(true)
    allow_any_instance_of(Object).to receive(:error_msg).and_return(true)
    # rubocop:enable all
  end
end

更新

  • 调整了问题中的规范

在此处输入图像描述

4

1 回答 1

1

SimpleCov uses Coverage#result module from Ruby standard library to check what was covered. Coverage#result gets reset for the file (this is my theory!) when you re-load the file using Kernel load.

Since you are loading data.rake before each block gets executed, only the last spec in the rspec file gets reported in results.

You can fix this by loading the tasks once before the all the examples are run using before(:all)

A quick change in your shared context like below will give you the coverage report you want.

RSpec.shared_context 'rake' do
  let(:invoke_task) { Rake.application[task_name] }
  let(:highline) { instance_double(HighLine) }

  before(:all) do
    Rake.application = Rake::Application.new
    Rails.application.load_tasks
  end    

  before do
    allow(HighLine).to receive(:new).and_return(highline)
    # rubocop:disable all
    allow_any_instance_of(Object).to receive(:msg).and_return(true)
    allow_any_instance_of(Object).to receive(:error_msg).and_return(true)
    # rubocop:enable all
  end
end
于 2017-02-11T05:20:48.583 回答