Как я могу издеваться над оператором Ruby «требовать» в RSpec? - PullRequest
0 голосов
/ 07 июня 2019

У меня есть программа Ruby cli, которая может дополнительно загружать указанный пользователем файл через require.Я хотел бы протестировать эту функциональность через RSpec.Очевидная вещь, которую нужно сделать - это посмеяться над требованием и убедиться, что это произошло.Примерно так:

context 'with the --require option' do
  let(:file) { "test_require.rb" }
  let(:args) { ["--require", "#{file}"] }
  it "loads the specified file"
    expect(...something...).to receive(:require).with(file).and_return(true)
    command.start(args)
  end
end

(это просто напечатано, а не скопировано / вставлено - реальный код может затенить вопрос.)

Независимо от того, что я пытаюсь, я не могу захватитьrequire, даже если это происходит (это поднимает LoadError, так что я вижу это).Я пробовал разные вещи, в том числе самые очевидные:

expect(Kernel).to receive(:require).with(file).and_return(true)

или даже:

let(:kernel_class) { class_double('Kernel') }
kernel_class.as_stubbed_const
allow(Kernel).to receive(:require).and_call_original
allow(Kernel).to receive(:require).with(file).and_return(true)

, но, кажется, ничто не зацепило require

Предложения

1 Ответ

6 голосов
/ 07 июня 2019

То есть require определяется как Kernel, но Kernel включается в Object, поэтому, когда вы вызываете require внутри этого контекста, необязательно модуль Kernel обрабатывает инструкцию.

Обновление

Я не уверен, что это точно решит вашу проблему, но он не страдает от странного поведения, показанного ниже:

file = 'non-existent-file'
allow(self).to receive(:require).with(file).and_return(true)
expect(self).to receive(:require).with(file)
expect(require file).to eq(true)

Рабочий пример

СТАРЫЙ Ответ:

Это неверно и существует только для потомков из-за полученных голосов "за".Кое как работает без allow.Мне бы понравилось, если бы кто-то мог объяснить, почему, как я предполагал, он должен поднять вместо этого.Я считаю, что проблема связана с and_return, где это не является частью ожиданий.Я предполагаю, что мы проверяем только то, что сам получил require, with_file, и что часть and_return является просто передачей сообщения (таким образом, мой обновленный ответ)

Вы все еще можете заглушить этовот так:

file = 'non-existent-file.rb'
allow_any_instance_of(Kernel).to receive(:require).with(file).and_return(true)
expect(self).to receive(:require).with(file).and_return(true)
require file

Так как я не совсем уверен относительно вашей точной реализации, так как вы запутали ее из-за вопроса, я не могу решить вашу точную проблему.

...