使用 rspec 和 vcr 测试 Thor 脚本

Testing a Thor script with rspec and vcr

我构建了一个连接到 HTTP API 的 Thor 脚本来执行一些非常简单的操作。我已经为后端编写了测试代码,但 Thor 脚本基本上未经测试,这是非常次优的。

我的第一个方法是捕获命令本身的输出并针对此类输出编写测试,结果测试速度慢得令人惊讶。

expect(`bin/script foo`).to eq('bar')

然后我尝试同时使用 webmockvcr 但是使用这种方法 none 这些框架被调用,即使我模拟了未使用的确切请求,大多数可能是因为 webmockvcr 都无法连接到 thor 脚本。

有没有人为此找到好的解决方案?直接调用 Thor 脚本 (Thorclass.action('bar')) 就足以满足我的口味,但我还没有找到实现它的方法。 有什么建议吗?提前致谢。

Thor 是包装器

  • 我倾向于将 Rake、Thor 和朋友视为您代码的另一个接口
  • 我让我的 Thor/Rake 代码尽可能小
  • 所有生产代码都保存在标准中 Ruby class
  • 这意味着通过 VCR 进行单元测试变得非常容易
  • 还允许您在另一个界面中重用您的生产代码:例如一个 Rails 控制器

例子

雷神包装器

bin/seed

#!/usr/bin/env ruby
require "thor"

class Seed < Thor
  desc "budgets", "Seeds budgets"
  def budgets
    puts 'Seeding currencies...'
    SeedBudgets.new.call
    puts 'Done.'
  end
end

Seed.start

For more details on command line Thor see this excellent walkthrough

生产代码

lib/services/seed_budgets.rb

class SeedBudgets
  def initialize
    # I find an initialize helpful for injecting dependencies
  end

  def call
    # Code goes here
  end
end

单元测试

test/services/seed_budgets_test.rb

require 'minitest/autorun'
require 'vcr'

VCR.configure do |config|
  config.cassette_library_dir = 'fixtures/vcr_cassettes'
  config.hook_into :webmock
end

class SeedBudgetsTest < Minitest::Test
  def test_seeds_one_budget
    VCR.use_cassette('one_budget_from_api') do
      SeedBudgets.new.call
      assert_equal 1, Budget.count
    end
  end
end

这将使您能够将命令行界面与实际代码分离。

然后 Thor 将成为您实际代码的一个非常薄的包装器。

欢迎 post 更详细的代码,我可以提供更多帮助。 :)