рспэк издевается: проверить ожидания в нем" должны " методы?


Я пытаюсь использовать насмешку rspec для настройки ожиданий, которые я могу проверить в методах it "should"... но я не знаю, как это сделать... когда я позвоню ... should_receive методы на макете, он проверяет ожидаемый вызов, как только before: all метод завершает работу.

Вот небольшой пример:

describe Foo, "when doing something" do
 before :all do
  Bar.should_recieve(:baz)
  foo = Foo.new
  foo.create_a_Bar_and_call_baz
 end

 it "should call the bar method" do
  # ??? what do i do here?
 end
end

Как я могу проверить ожидаемый вызов в методе' it 'should'? нужно ли мне использовать mocha или другую насмешливую структуру вместо RSpec? или ...??

5 3

5 ответов:

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

describe Foo, "when frobbed" do
  before :all do
    @it = Foo.new

    # Making @bar a null object tells it to ignore methods we haven't 
    # explicitly stubbed or set expectations on
    @bar = stub("A Bar").as_null_object
    Bar.stub!(:new).and_return(@bar)
  end

  after :each do
    @it.frob!
  end

  it "should zap a Bar" do
    @bar.should_receive(:zap!)
  end

  it "should also frotz the Bar" do
    @bar.should_receive(:frotz!)
  end
end

Кстати, хотя это работает, я не большой поклонник шаблона Bar.stub!(:new); обычно я предпочитаю передавать коллаборационистов через необязательные аргументы, например @it.frob!(@bar). Если не задан явный аргумент (например, в производственном коде), то сотрудник может быть нарушено: def frob!(bar=Bar.new). Это делает тесты немного менее привязанными к внутренней реализации.

Как правило, вы никогда не должны помещать ожидание в блок before. Блоки before предназначены для настройки состояния, которое совместно используется в нескольких примерах (блокиit). Поместите ожидание в сам пример. Например:

describe Foo, "when doing something" do
  before :all do
   @foo = Foo.new
  end

  it "should call the bar method" do
    Bar.should_recieve(:baz)
    @foo.create_a_Bar_and_call_baz
  end
end
Обычно я стараюсь, чтобы мой блок describe описывал конкретное состояние (например, describe Car, "given a full tank of gas"), а не описывал действие.

Метод should_receive используется для настройки макета объекта для возврата чего-то определенного при вызове метода. Вот пример:

Bar.should_recieve(:baz).with.({:arg1 => 'this is arg1', :arg2 => 'this is arg2'}).and_return(true)

Как правило, с помощью BDD вы хотите проверить поведение вашего приложения. Проверка того, какие методы были вызваны для построения правильного поведения, не имеет значения. Если однажды вы решите удалить метод baz, вам придется обновить тесты, даже если поведение вашего приложения не изменится.

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

Я знаю, что это старый разговор, но на всякий случай, если кому-то все еще нужен правильный ответ, здесь я пишу пример о том, как проверить rpec издевается над зрителями:

require 'spec'
require 'spec/mocks'
include Spec::Mocks::ExampleMethods

o = mock('object')
o.should_receive(:respond_to?).once

space = Spec::Mocks::Space.new
space.add o

# here we should invoke methods, o.respond_to?:foo for instance

space.verify_all

Ура

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

Если нет, то это не столько контекст, сколько часть наблюдения, что делает его естественным принадлежать блоку it.