Могу ли я реализовать внедрение зависимостей в моих тестах RSpec? - PullRequest
0 голосов
/ 29 мая 2018

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

RSpec.shared_examples "changing status" do |arguments|
  /* ... */

  it_behaves_like "action requiring proper user logged in to be successful", action

  context "- when the required logged user is logged in" do
    before(:each) do
      /* ... */
    end
    context "and when the reservation has an allowed status" do
      /* ... */
    end
    context "and when the reservation has a not allowed status" do
      /* ... */
    end
  end
end
RSpec.shared_examples "action requiring proper user logged in to be successful" do |action|
  context "- when the logged in user is not the required logged user" do
    before(:each) do
      login(incidental_user)
    end
    it_behaves_like "unsuccessful attempt to change the reservation", action
  end
  context "- when there's no user logged in" do
    it_behaves_like "unsuccessful attempt to change the reservation", action
  end
end

Итак, я хотел бы внедрить код из моего контекста "when the required logged user is logged in" в мой общий примерсделать это чистым.Я пытался сделать это с анонимными блоками кода и ключевым словом yield:

RSpec.shared_examples "changing status" do |arguments|
  /* ... */

  it_behaves_like "action requiring proper user logged in to be successful", action do
    before(:each) do
      /* ... */
    end
    context "and when the reservation has an allowed status" do
      /* ... */
    end
    context "and when the reservation has a not allowed status" do
      /* ... */
    end
  end

end
RSpec.shared_examples "action requiring proper user logged in to be successful" do |action|
  context "- when the required logged user is logged in" do
    yield
  end
  context "- when the logged in user is not the required logged user" do
    before(:each) do
      login(incidental_user)
    end
    it_behaves_like "unsuccessful attempt to change the reservation", action
  end
  context "- when there's no user logged in" do
    it_behaves_like "unsuccessful attempt to change the reservation", action
  end
end

Но, к сожалению, он получает эту ошибку:

LocalJumpError: блок не задан (yield)

Итак, как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Наконец я решил свою проблему с помощью лямбды:

RSpec.shared_examples "changing status" do |arguments|
  /* ... */

  it_behaves_like "action requiring proper user logged in to be successful", action, -> {
    before(:each) do
      /* ... */
    end
    context "and when the reservation has an allowed status" do
      /* ... */
    end
    context "and when the reservation has a not allowed status" do
      /* ... */
    end
  }
end
RSpec.shared_examples "action requiring proper user logged in to be successful" do |action, successful_behavior|
  context "- when the required logged user is logged in" do
    successful_behavior.()
  end
  context "- when the logged in user is not the required logged user" do
    before(:each) do
      login(incidental_user)
    end
    it_behaves_like "unsuccessful attempt to change the reservation", action
  end
  context "- when there's no user logged in" do
    it_behaves_like "unsuccessful attempt to change the reservation", action
  end
end
0 голосов
/ 30 мая 2018

Интересный вопрос.

Вы можете сделать это в одном инкапсулированном примере, но есть другой, более понятный способ IMO:

Создайте отдельные shared_example s для положительных и отрицательных тестов,Отрицательный, который вы сработали, так что вы хороши (просто измените имя, чтобы было ясно, что это отрицательный набор тестов).

И положительный может выглядеть так:

RSpec.shared_examples 'restricted action with logged in user' do
  before { login(authorized_user) }

  specify do
    expect_stuff_typical_for_logged_in_user
    # e.g. expect(response).to be_success
  end
end

А затем включите его в свои спецификации с include_examples, как это

context do 
  include_examples 'restricted action with logged in user'
  # you're "inside" the context of included examples so you can 
  # write down extra expectations specific for each action
end

Может быть, у вашей положительной части нет общих ожиданий, простоустанавливает контекст - вы можете рассмотреть возможность использования shared_context для четкой передачи ваших намерений.

Вы можете объединить все это в одном общем примере, например так:

RSpec.shared_examples "action requiring proper user logged in to be successful" do
  # set up the context for positive scenarios, so you can include it with 
  # `include_examples` and be "inside" this context
  before { login(authorized_user) }

  context "- when the logged in user is not the required logged user" do
    before(:each) do
      login(incidental_user)
    end
    it_behaves_like "unsuccessful attempt to change the reservation"
  end
  context "- when there's no user logged in" do
    before { log_out_people }
    it_behaves_like "unsuccessful attempt to change the reservation"
  end
end

Тамдве проблемы с этим.Сначала вы устанавливаете позитивный контекст, а затем вы должны отменить его в негативных примерах (кажется вонючий ).Во-вторых, может быть не очевидно, что происходит в спецификациях.Они будут выглядеть так:

context do
  include_examples 'action requiring proper user logged in to be successful'

  specify do
    expect(response).not_to be_redirect
  end

  context 'when user have not seen changes TOS' do
    before { }
    specify do
      expect(session[:notice]).to eq 'Please read new TOS'
    end
end 

И совсем не ясно, что отрицательные примеры покрыты.

И затем, если в любом месте вам нужны нестандартные ожидания для отрицательного случая - вам все равно придется их разделить.

Вы можете решить пойти любым путем, осознавая компромиссы.

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