Как протестировать OptionParser с помощью Rspe c - параметры RSpe c во время тестирования сохраняются в массиве ARGV - PullRequest
1 голос
/ 10 июля 2020

Я изучаю ruby и пытаюсь написать модульный тест с rspe c для следующего метода:

def get()
    options = {}
    OptionParser.new do |opt|
      opt.banner = 'Usage: validate-gitlab-ci [options]'
                    
      opt.on('-f', '--yaml YAML-PATH', 'Path to .gitlab-ci.yml') { |o| options[:yamlFile] = o }
      opt.on('-l', '--base-url GitLab url', 'GitLab API url') { |o| options[:baseUrl] = o + API_PATH }
      opt.on('-t', '--timeout[TIMEOUT]', Integer, 'Api timeout in seconds') { |o| options[:timeout] = o || 10 }
      opt.on('-v', '--version', 'Program version') { |o| options[:version] = o }
    end.parse!
                
    validateUrl!(options[:baseUrl])
    validateYamlFile!(options[:yamlFile])

    @baseUrl = options[:baseUrl]
    @pathToYamlFile = options[:yamlFile]
end

Пока что код для моего модульного теста :

RSpec.describe Gitlab::Lint::Client::Args do
    describe "#get" do
        context "when arguments are valid" do
            it "sets baseUrl and pathToYamlFile" do
                io = StringIO.new
                io.puts "glab-lint --base-url=https://example.com --yaml=valid.ym\n"
                io.rewind

                $stdin = io
                args = Gitlab::Lint::Client::Args.new
                args.get()
                expect(args.baseUrl).to.eq("https://example.com")
            end
        end
    end
end

Я пытаюсь имитировать STDIN для OptionParser . Однако при выполнении теста отображается следующая ошибка:

 OptionParser::InvalidOption:
       invalid option: --pattern

Это возникает при end.parse! строка в методе get ()

Удалось ли кому-нибудь протестировать OptionsParser с имитацией stdin?

Update

Я думаю, что происходит, RSpe c варианты, например - шаблон ?? захватываются в STDIN и передаются в скрипт ??? Или .... RSpe c использует параметры стандартного ввода ??

Чтение этого сообщения , похоже, наводит на мысль, что желаемая функциональность невозможна с RSpe c .... Если это действительно так, я перейду к использованию альтернативных тестовых фреймворков в будущем для проектов CLI, которые используют ARGV. Предлагается обходной путь здесь , но он предлагает использовать переменные среды для захвата аргументов командной строки. В этом случае потребуется дальнейший рефакторинг тестируемого программного обеспечения исключительно для соответствия возможностям тестовой среды RSpe c !!

Если я добавлю put для отображения содержимого ARGV в тестовом сценарии, он подтверждает, что это так, с этим выводом:

--pattern
spec/**{,/*/**}/*_spec.rb
[--base-url=https://gitlab.com --yaml=valid.ym]

Итак ... как полный newb ie для RSpe c ..... мои варианты:

  1. Обновить подпись метода get для принятия массива args:
def get(args)
    options = {}
    OptionParser.new do |opt|
    ...
    end.parse!(args)
end

Это задерживает проблему с тестированием кода, который считывает из ARGV дальше по иерархии вызовов

Измените ARGV, сдвинув первые два аргумента из массива, а затем после завершения теста восстановите ARGV в исходное состояние. Похоже, что-то подобное уже пробовали здесь безуспешно.

Другая конфигурация, о которой я не знаю как новичок ie для RSpe c

Изучите альтернативные варианты, например minitest, которые, возможно, не изменяют массив ARGV ??

Приветствуется дополнительная информация относительно вариантов 3 и 4. ...

1 Ответ

0 голосов
/ 11 июля 2020

Вы можете использовать RSpe c для имитации STDIN. Например:

STDIN.should_receive(:read).and_return("glab-lint --base-url=https://example.com --yaml=valid.yml")

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

...