Как я могу заглушить глобальную функцию, вызываемую из конструктора? - PullRequest
0 голосов
/ 11 апреля 2019

Я пытаюсь заглушить глобальную функцию, вызываемую из конструктора. Я использую Rspec и Rspec-mocks. Вот код для тестирования:

def foo
  'foo'
end

class Bar
  def initialize
    @bar = foo
  end

  def bar
    @bar
  end
end

А вот и тест:

describe 'bar'
  it 'calls foo' do
    expect(self).to receive(:foo) { 'bar' }

    expect(Bar.new.bar).to eq('bar')
  end
end

Тест не пройден со следующим сообщением:

     Failure/Error: expect(Bar.new.bar).to eq('bar')

       expected: "bar"
            got: "foo"

       (compared using ==)

Как отключить глобальную функцию foo?

PS: expect(self).to receive(:foo) { 'bar' } работает должным образом, если foo вызывается из другой глобальной функции.

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Самое простое решение, вероятно, использует #allow_any_instance_of, который работает, потому что "глобальные" функции на самом деле являются Kernel методами в Ruby. Но так как документация не одобряет заглушки классов во всем мире, я подумал, что по крайней мере предложу альтернативу:

def foo
  'foo'
end

class Bar
  def self.get_foo
    foo
  end

  def initialize
    @bar = self.class.get_foo
  end

  def bar
    @bar
  end
end

и

describe Bar do
  it 'gets foo' do
    expect(Bar).to receive(:get_foo).and_return('bar')

    expect(Bar.new.bar).to eq('bar')
  end
end

Конечно, если это возможно, лучше отказаться от метода Kernel и просто использовать метод класса.

0 голосов
/ 11 апреля 2019
allow_any_instance_of(Bar).to receive(:foo) { 'bar' }
...