我构建了一个 Thor 脚本,它连接到 HTTP API 来执行一些非常简单的操作。我已经为后端编写了测试代码,但 Thor 脚本基本上未经测试,这不是最理想的。
我的第一个方法是捕获命令本身的输出并针对此类输出编写测试,结果测试的速度非常慢。
expect(`bin/script foo`).to eq('bar')
然后,我尝试使用 webmock
和 vcr
但使用这种方法,这些框架都不会被调用,即使我模拟了确切的请求,大多数模拟都未使用可能是因为 webmock
和 vcr
都无法 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/