使用rspec和vcr测试Thor脚本

时间:2018-12-18 16:00:00

标签: ruby rspec thor vcr

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

我的第一种方法是捕获命令本身的输出并针对该输出编写测试,结果测试出奇的慢。

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

然后,我尝试同时使用webmockvcr,但是使用这种方法,即使我模拟了该模拟的确切请求未使用,也没有调用这些框架,这很可能是因为{{1 }}和webmock无法插入脚本。

有人找到了一个很好的解决方案吗?根据我的口味,直接调用Thor脚本(vcr)就足够了,但是我还没有找到一种方法。 有什么建议吗?预先感谢。

1 个答案:

答案 0 :(得分:1)

雷神是包装纸

  • 我倾向于将Rake,Thor和朋友视为您代码的另一个界面
  • 我将Thor / Rake代码保持尽可能小
  • 所有生产代码都保存在标准的Ruby类中
  • 这意味着通过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变成了围绕您实际代码的非常薄的包装。

随时发布更多详细的代码,我可以提供更多帮助。 :)