Есть ли ожидание RSpe c для какого-либо экземпляра данного вида? - PullRequest
2 голосов
/ 27 апреля 2020

Мне нужно покрыть мой код Ruby на Rails тестами. Я использую RSpe c для тестирования.

Есть ли способ, как смоделировать вызовы на экземплярах в зависимости от их вида? (kind_of?). Я хочу проверить, вызваны ли дети данного родительского класса. Я бы ожидал что-то вроде allow_any_kind_of метода, похожего на allow_any_instance_of. Однако я не могу найти ничего подобного.

Вот мой пример кода. У меня есть Base класс и несколько его детей. При тестировании не имеет значения, какой именно ребенок используется.

class Parent
  def my_method; end
end
class ChildA < Parent; end
class ChildB < Parent; end

class App
  def apply  
    [ChildA.new, ChildB.new].all? { |c| c.my_method }
  end
end

Мой тест RSpe c. Сбой, потому что ни ChildA, ни ChildB не являются экземплярами класса Parent. У меня может быть несколько allow_any_instance_of, чтобы охватить всех детей Parent, но я хотел бы сделать это простым, поскольку в реальном коде будет гораздо больше детей.

context "#apply" do
  before do
    allow_any_instance_of(Parent).to receive(:my_method).and_return(true)
  end

  it "returns true" do
    expect(subject.apply).to be_truthy
  end
end

1 Ответ

0 голосов
/ 28 апреля 2020

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

вы можете переписать его так, как показано ниже:

class App
 def initialize(params_hash)
   @children = params_hash[:children] || [ChildA.new, ChildB.new]
 end

 def apply  
   children.all? { |c| c.my_method }
 end

 private

 attr_reader :children
end

, тогда в ваших тестах вы могли бы сделайте что-то похожее на следующее:

describe "#apply" do
  it "returns true" do
    children = [instance_double('SubClassA', my_method: true)]
    expect(children.first).to receive(:my_method)
    app = App.new(children: children)
    expect(app.apply).to be true
  end
end

использование expect_any_instance_of может быть возможным признаком запаха кода, всякий раз, когда я начинаю думать об его использовании, я делаю паузу и смотрю на свой код и проверяю, могу ли я написать это лучше, так что легко тестировать, а внедрение зависимостей облегчает тестирование кода.

здесь вы пытаетесь подключиться к методу apply и проверить, что он делает, но это так. Наш клиентский код не может проверить, что происходит внутри него. поэтому я бы вводил свои зависимости и возлагал на них свои ожидания всякий раз, когда для меня это оправданно и разумно.

...