使用 rspec 和 vcr 测试 Thor 脚本
Testing a Thor script with rspec and vcr
我构建了一个连接到 HTTP API 的 Thor 脚本来执行一些非常简单的操作。我已经为后端编写了测试代码,但 Thor 脚本基本上未经测试,这是非常次优的。
我的第一个方法是捕获命令本身的输出并针对此类输出编写测试,结果测试速度慢得令人惊讶。
expect(`bin/script foo`).to eq('bar')
然后我尝试同时使用 webmock
和 vcr
但是使用这种方法 none 这些框架被调用,即使我模拟了未使用的确切请求,大多数可能是因为 webmock
和 vcr
都无法连接到 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 更详细的代码,我可以提供更多帮助。 :)
我构建了一个连接到 HTTP API 的 Thor 脚本来执行一些非常简单的操作。我已经为后端编写了测试代码,但 Thor 脚本基本上未经测试,这是非常次优的。
我的第一个方法是捕获命令本身的输出并针对此类输出编写测试,结果测试速度慢得令人惊讶。
expect(`bin/script foo`).to eq('bar')
然后我尝试同时使用 webmock
和 vcr
但是使用这种方法 none 这些框架被调用,即使我模拟了未使用的确切请求,大多数可能是因为 webmock
和 vcr
都无法连接到 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 更详细的代码,我可以提供更多帮助。 :)