Заглушка, когда конструктор объекта создает другой объект

Итак, у меня есть код, которыйсильно упрощено, выглядит так:

class B
  def initialize opts
    @opts = opts
  end
end

class A
  def initialize opts
    # defaults etc applied to opts
    @b = B.new opts
  end
end

Другими словами, когда я инициализирую A параметрами, он создает B и передает ему измененный набор параметров.

Я хотел бы проверить, что B.new получает правильные аргументы. Прямо сейчас я делаю это так, используя RSpec/RR:

@b = Object.new
# stub methods on @b here
stub(B).new { |options|
  options[:foo].should == 'whatever'
  @b
}
A.new({:foo => 'whatever'})

Но у этого есть две проблемы.

Во-первых, я не могу создать реальную копию Bс реальными параметрами. Если я вызову B.new внутри блока, он вызовет версию с заглушкой и зациклится, пока стек не выскочит. Я могу установить @b = B.newперед заглушкой, но я еще не знаю параметры, которые будут переданы, что лишает смысла тест.

(И прежде чем кто-нибудь сообщит мне об этом, :да, согласно строгой догме модульного тестирования, тест A должен заглушать любые методы в B, а необходимость заглушать много означает, что ваш код плохой в первое место.)

Во-вторых, неправильно размещать shouldв настройках теста, а не в отдельном блоке it... do... endвпоследствии. Но так как я не могу создать настоящуюB(см. выше ), я также не могу допросить его пост -состояние строительства.

Любые идеи?

5
задан lambshaanxy 6 July 2012 в 05:01
поделиться