Тестирование сценария Thor с помощью rspec и vcr

Я создал скрипт Thor, который подключается к HTTP API для выполнения очень простых действий. Я закодировал тесты для серверной части, но сценарий Thor в основном не тестировался, что довольно неоптимально.

Мой первый подход заключался в том, чтобы зафиксировать вывод самих команд и написать тест для такого вывода, что неудивительно медленно.

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

Затем я попытался использовать как webmock, так и vcr, но при таком подходе ни один из этих фреймворков не вызывается, даже если я имитирую точный запрос, макет не используется, скорее всего, потому, что и webmock, и vcr не могут подключиться к скрипту thor.

Кто-нибудь нашел хорошее решение для этого? Прямого вызова сценария Thor (Thorclass.action('bar')) на мой вкус было бы достаточно, но я не нашел способа сделать это. Любое предложение? Заранее спасибо.


person ngw    schedule 18.12.2018    source источник


Ответы (1)


Тор - это обертка

  • Я склонен рассматривать Rake, Thor и их друзей как еще один интерфейс для вашего кода.
  • Я стараюсь, чтобы мой код Thor/Rake был как можно меньше.
  • Весь производственный код хранится в стандартном классе Ruby.
  • Это означает, что модульное тестирование с помощью видеомагнитофона становится невероятно простым.
  • Также позволяет повторно использовать ваш производственный код в другом интерфейсе: например. контроллер 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

Подробнее о командной строке Thor см. в этом отличном пошаговом руководстве

Производственный код

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 становится очень тонкой оболочкой вокруг вашего фактического кода.

Не стесняйтесь публиковать более подробный код, и я могу помочь больше. :)

person John Gallagher    schedule 18.12.2018