методы тестирования в блоках с RSpec - PullRequest
8 голосов
/ 11 мая 2011

В моем упрощенном примере того, что я на самом деле делаю, скажем, у меня есть 2 вызова в базу данных:

Repo.add( something_stringy )
Repo.remove( something_floaty )

и я хочу использовать макеты для вызовов базы данных, поскольку реальные вызовы будут проверены в другом месте:

let(:repo){
  repo = double("Repo")
  repo.should_receive(:add).with(instance_of(String))
  repo.should_receive(:remove).with(instance_of(Float))
  repo
}

before { FakeKlass.const_set :Repo, repo }

все нормально, но теперь, если я заверну вызовы в транзакции, я немного озадачен:

Repo.transaction do
  # ... some error checking in here somewhere...
  Repo.add( something_stringy )
  Repo.remove( something_floaty )
end

потому что, если я напишу макет, который получает transaction, он получит вызов, но все в блоке не будет вызвано, и я получу:

ожидается: 1 раз получил: 0 раз

для всех остальных издевательств. Кто-нибудь сможет показать мне, как я должен написать свою спецификацию, чтобы справиться с этим? Я попытался прочитать соответствующую страницу в книге RSpec по around(:each), но это было для меня почти так же ясно, как и грязь.

Любая помощь очень ценится.

1 Ответ

12 голосов
/ 12 мая 2011

Вы можете использовать #and_yield, чтобы получить доход из цепочки ожиданий:

repo.should_receive( :transaction ).and_yield

Вам также не нужно устанавливать удвоение, чтобы заглушить методы в вашем классе Репо.Например, ваша установка может быть написана:

before( :each ) do
    Repo.should_receive( :transaction ).and_yield
    Repo.should_receive( :add ).with( instance_of(String) )
    Repo.should_receive( :remove ).with( instance_of(Float) )
end

Вы можете также рассмотреть возможность использования stub вместо should_receive, поскольку это не устанавливает ожидания:

before( :each ) do
    Repo.stub( :transaction ).and_yield
    Repo.stub( :add )
    Repo.stub( :remove )
end

В общем, вы должны использовать should_receive только тогда, когда вы хотите проверить взаимодействие между двумя объектами.Мое личное правило таково: если оно появляется в before, используйте stub;если это в примере, особенно с определенным значением, используйте should_receive.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...