ruby - 使用 rspec 和 vcr 测试 Thor 脚本

标签 ruby rspec thor vcr

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

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

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

然后,我尝试使用 webmockvcr 但使用这种方法,这些框架都不会被调用,即使我模拟了确切的请求,大多数模拟都未使用可能是因为 webmockvcr 都无法 Hook 到雷神脚本。

有没有人找到一个好的解决方案?直接调用 Thor 脚本 (Thorclass.action('bar')) 就足以满足我的口味,但我还没有找到一种方法来做到这一点。 有什么建议吗?提前致谢。

最佳答案

Thor 是一个包装器

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

示例

雷神包装

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 就变成了你实际代码的一个非常薄的包装。

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

关于ruby - 使用 rspec 和 vcr 测试 Thor 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53836815/

相关文章:

ruby-on-rails - 如何使用 RSpec 测试生成器

ruby - 用于分解方法定义的惯用 Ruby

rspec - 在 View 规范之间共享代码

ruby-on-rails - RSpec - stub 实例方法

ruby - 我如何测试我的 Ruby 代码在捕获符号时做了什么? (R规范)

ruby - 执行位于 bundle 的 gem 中的 Thor 任务

ruby - 将 thor 用于复杂的命令行工具

ruby - 雷神中的命令别名

ruby - 将十六进制字符串添加到二进制文件的内容之前

ruby-on-rails - 关于在生产环境中使用anyenv、rbenv、ndenv,CentOS7.*