2016-01-27 4 views
0

Я использую apartment gem для управления приложением Rails с несколькими арендаторами.Блок RSpec вокруг() ведет себя отличным от a before() + after()

Боковое примечание: Если вы не знакомы с драгоценным камнем, переключение квартир просто переключает схему, используемую на задней панели DB Postgres. Вы меняете квартиросъемщиков с Apartment::Tenant.switch!(apartment)

У меня есть несколько тестов, которые проверяют поведение в контексте конкретного арендатора квартиры. Для этого я использую ниже настройки (пример, показанные для спецификации контроллера)

RSpec.describe MyController, type: :controller do 
    before(:each) do 
    # Some global before() setup 
    end 

    context "foo apartment" do 

    ### Option 1 - Using the around() hook 
    around(:each) do |example| 
     begin 
     Apartment::Tenant.switch!("foo") 
     example.run 
     ensure 
     Apartment::Tenant.switch!("public") 
     end 
    end 

    ### Option 2 - Independent before() + after() hooks 
    before(:each) { Apartment::Tenant.switch!("foo") } 
    after(:each) { Apartment::Tenant.switch!("public") } 


    it "tests that the foo apartment is being used" do 
     expect(Apartment::Tenant.current).to eq("foo") 
    end 
    end 
end 

Как вы можете видеть, есть два подхода к настройке теста. Один использует крюк around(), а другой выполняет то же самое, но независимо использует крюки и after().

Я бы предположил, что оба подхода эквивалентны и взаимозаменяемы. Но на удивление работает только вариант 2.

Есть ли причина для такого поведения? Выполняется ли блок around() в другом порядке, чем блок before()?

+1

основе [Docs] (https://www.relishapp.com/rspec/rspec-core/v/3-4/docs/hooks/around-hooks), 'around' выполняет аналогичную цель как' before' и 'after'. Но «крючки« вокруг »не разделяют состояние с примером, как делают« перед »и« после »крючки». Проверьте документы; там есть множество примеров. – orde

+0

Я думаю, что на это отвечает, я пропустил это, когда прочитал документы. Благодаря! Если вы хотите переместить свой комментарий к ответу, я был бы рад отметить его как ответ. – user2490003

+1

Также обратите внимание, что ваш #some глобальный блок before() global будет фактически запущен внутри блока вокруг, что, скорее всего, является причиной здесь, так как я предполагаю, что глобальный блок настройки сбрасывает Арендатора –

ответ

2

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

around_before 
    global before() setup block 
    example runs 
around_after 

Если глобальный блок установки устанавливает жильца по умолчанию или что-то будет перезаписана, что вы делаете в вашем вокруг блока

с вариантом 2 вы получаете

global before() setup block 
before block 
example runs 
after block 
Смежные вопросы