На момент написания статьи (Puppet 6.6.0, Rspec-puppet 2.7.5) весь бизнес насмешливых функций Puppet, к сожалению, остается беспорядочным.Это не поможет тому, что rspec-puppet docs по-прежнему ссылается на устаревший Ruby API для функций.
Проблема, с которой вы сталкиваетесь, заключается в том, что, как сказал Джон Боллинджер в комментариях,у вас есть экземпляр компилятора, который запускается при загрузке файлов Rspec, а затем утверждения в it
блоках, которые запускаются позже.
Помните, что Rspec (сам Rspec, ничего общего с Puppet) работает в два этапа:
- Все блоки
describe
и context
оцениваются во время загрузки файлов Rspec. - Блоки
it
, сами примеры, кэшируются и оцениваютсяпозже.
На это есть ответ автора Rspec на Stack Overflow здесь , который я рекомендую посмотреть.
Итак, чтобы избежать каталогабудучи скомпилированным для каждого отдельного примера - что сделало бы Rspec-puppet слишком медленным - компиляция кэшируется до выполнения it
примеров.
Так что вы можете сделать?
Option1 - Используйте Tom Poulton's rspec-puppet-utils .
Это имеет преимущество готового решения, которое заботится о том, чтобы высмеивать ваши функции Puppet через хорошо известный интерфейс и использовать expected
Функция, реализованная Томом, позволяет также вызывать перекомпиляцию каталогов в различных примерах.
Недостатки могут заключаться в том, что он использует Mocha, а не Rspec-mocks, он использует устаревший API Ruby - но затем то же самое делает Rspec.Куклы-куклы!- и это не было принято с 2017 года.
Таким образом, вы можете переписать свои тесты следующим образом:
require 'spec_helper'
require 'rspec-puppet-utils'
def mock_mmf(return_value)
MockFunction.new('my_mocked_function').expected.returns(return_value)
end
describe 'test' do
context 'numero uno' do
before { mock_mmf('foo') }
it { should contain_file('under_test').with_content('foo') }
end
context 'numero duo' do
before { mock_mmf('bar') }
it { should contain_file('under_test').with_content('bar') }
end
end
Вариант 2 - Украсть часть кода Тома - патч обезьяны Rspec-puppet
Однако внутри кода Тома просто обезьяна исправляет Rspec-puppet, и вы можете просто украсть немного, что делает это, и рефакторировать ваши примеры следующим образом:
require 'spec_helper'
require 'rspec-puppet/cache'
module RSpec::Puppet ## Add this block
module Support
def self.clear_cache
@@cache = RSpec::Puppet::Cache.new
end
end
end
def mock_mmf(return_value)
RSpec::Puppet::Support.clear_cache ## ... and this line
Puppet::Parser::Functions.newfunction(:'my_mocked_function', type: :rvalue) do |_args|
return return_value
end
end
describe 'test' do
context 'numero uno' do
before { mock_mmf('foo') }
it { should contain_file('under_test').with_content('foo') }
end
context 'numero duo' do
before { mock_mmf('bar') }
it { should contain_file('under_test').with_content('bar') }
end
end
Вариант 3 -найти лучший способ
Если вы будете долго искать в других модулях Puppet, вы можете найти лучшее решение - даже решения, использующие API функций Puppet 4.Тем не менее, я думаю, это не имеет большого значения для целей вашего теста, если поддельная функция возвращает ожидаемый вами ответ.