Популярная поисковая система привела меня сюда, так как в моем случае я видел, как тесты терпели неудачу, когда #invoke
использовалось более одного раза для данного теста. Приведенное ниже решение основано на ответе @ dave-newtown.
Проблема возникает из-за того, что на момент написания (Rake v12) #invoke
запускает задачу только один раз, например:
RSpec.describe "demo:test" do
it "runs" do
expect(SomethingWeAreInvoking).to eql(ProofIfWasInvoked)
Rake::Task["demo:test"].invoke
end
it "runs" do
expect(SomethingWeAreInvoking).to eql(ProofIfWasInvoked)
Rake::Task["demo:test"].invoke
end
end
... может быть пройден для любого из it
, который запускается первым, если тест хорошо написан и задача вызывается правильно, но затем всегда будет терпеть неудачу для второго it
, как в данном Rake.application
, использование #invoke
только когда-либо запускает задачу один раз. Состояние «выполнялось до», по-видимому, запоминается внутри экземпляра Rake.application
.
Да, это означает, что, по крайней мере, в Rake v12, как было протестировано, множество онлайн-статей, показывающих, как тестировать задачи Rake, (fo) неверны или им это сойдет с рук, потому что они показывают только один тест. для любой заданной задачи в своих примерах.
Мы могли бы использовать #execute
Rake, но он не запускает зависимые задачи, поэтому создает свой собственный набор проблем и еще больше отдаляет нас от тестирования стека Rake, как если бы он вызывался из командной строки.
Вместо этого гибрид принятого ответа вместе с другими кусочками из Интернета дает эту альтернативу:
require 'spec_helper'
require 'rake'
RSpec.describe 'demo:test' do
before :each do
Rake.application = Rake::Application.new
Rake.application.rake_require 'lib/tasks/demo_tasks', [Rails.root.to_s], []
Rake::Task.define_task(:environment)
end
it 'runs' do
expect(SomethingWeAreInvoking).to eql(ProofIfWasInvoked)
Rake.application.invoke_task('demo.test')
end
it 'runs with a parameter' do
expect(SomethingWeAreInvoking).to eql(ProofIfWasInvoked)
Rake.application.invoke_task('demo.test[42]')
end
end
- Он готовит грабли на
before :each
.
- Каждый раз создается новый
Rake.application
; это означает, что мы можем использовать invoke
в любом количестве тестов, хотя и только один раз в каждом отдельном тесте.
- Если бы мы просто использовали готовый экземпляр
Rake.application
, мы могли бы просто написать Rake.application.rake_require 'tasks/demo_tasks'
, поскольку все пути и т. д. настроены, но поскольку нам определенно нужен новый экземпляр приложения Rake для каждого теста, чтобы не «загрязнять» его состояние во всех тестах требуется «от руки» форма от @dave-newtown.
- Я использую
Rake.application.invoke_task
вместо Rake::Task[...].invoke
. Это ставит синтаксис для аргументов в соответствие с тем, что используется в командной строке Rake, что я считаю более «точным» и естественным способом тестирования задач, которые принимают аргументы.
Да, это действительно означает, что, по крайней мере, в Rake v12, как было протестировано, множество онлайн-статей, показывающих, как тестировать задачи Rake, неверны или им это сойдет с рук, потому что они показывают только один тест для любого заданного задание на своих примерах. Вероятно, ранние версии Rake не вели себя таким образом, поэтому эти статьи были правильными на момент их написания.
Надеюсь, кто-то найдет это полезным.
Справочные статьи:
(подсказка поисковой системы: тестирование рейка rspec test invoke вызывается только один раз)
person
Andrew Hodgkinson
schedule
18.09.2019