Подтвердить что ты не робот

RSpec, ожидается изменение с несколькими значениями

Возможный дубликат:
Возможно ли, чтобы RSpec ожидал изменения в двух таблицах?

it "should create a new Recipe" do
  expect { click_button submit }.to change(Recipe, :count).by(1)
end

Это позволяет мне проверить, что модель "Рецепт" имеет еще одну запись, но я хотел бы также проверить, что модель "Ингредиент" имеет еще одну запись. Блок ожидания может быть выполнен только один раз, поскольку форма уже отправлена.

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

4b9b3361

Ответ 1

Я бы предложил DRYing его, переопределив тему теста (и используя stabby lambdas для удовольствия):

describe "recipe creation" do
  subject { -> { click_button submit } }
  it { should change(Recipe, :count).by(1) }
  it { should change(Ingredient, :count).by(1) }
end

Обновить. Хотя он может выглядеть менее сухим, в наши дни я бы, вероятно, продолжал использовать синтаксис expect, так как он рекомендуется и я вообще удаляюсь от should, но, возможно, сделаю некоторые незначительные изменения для удобочитаемости spec:

describe "recipe creation" do
  let(:creating_a_recipe) { -> { click_button submit } }

  it "changes the Recipe count" do
    expect(creating_a_recipe).to change(Recipe, :count).by(1)
  end

  it "changes the Ingredient count" do
    expect(creating_a_recipe).to change(Ingredient, :count).by(1)
  end
end

Примечание: вы можете видеть в документации RSpec для change -сервера, в которой expect используются фигурные скобки. Это, конечно, правильно, но причина, по которой стандартная скобка работает в этом примере, заключается в том, что код, изменяющий изменчивое состояние (содержится в creating_a_recipe), находится в лямбда, который вызывается при передаче в expect в качестве параметра.

Независимо от этого, в этом случае можно успешно использовать expect(creating_a_recipe) или expect { creating_a_recipe }, и в зависимости от того, какой вы используете, это зависит от личных предпочтений.

Ответ 2

Вы можете абстрагировать все это на вспомогательный метод

def test_creation_of(model)
  it "should create a new #{model}" do
    expect { click_button submit }.to change(model.constantize, :count).by(1)
  end
end

Но я бы рекомендовал это, если вы сделаете это для многих моделей. Иначе это просто сделает код более трудным для чтения. Если вы это сделаете, лучше всего поместить его в помощника спецификации.

Кроме того, на основе других прецедентов в ваших тестах вы можете передать объект Const вместо строки (как я использовал в примере выше).

затем

it "should create a new Recipe" do
  test_creation_of( 'Recipe' )
  test_creation_of( 'Ingredient' )
end