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

Утверждение нескольких ожиданий изменений в рамках одного лямбда-запроса

У меня такой тест:

lambda { post("/api/users", parameters) }.should change(User,:count).by(1)
lambda { post("/api/users", parameters) }.should_not change(ActionMailer::Base, :deliveries)

Но я хочу сделать это вот так:

lambda { post("/api/users", parameters) }.should change(User,:count).by(1).and_not change(ActionMailer::Base, :deliveries)

Можно ли сделать это без необходимости двух почтовых вызовов?

Спасибо

4b9b3361

Ответ 1

Я нашел решение для его проверки.

lambda{
  lambda { post("/api/users", params) }.should change(User,:count).by(1)
}.should change(ActionMailer::Base.deliveries, :count).by(1)

Ответ 2

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

Во-вторых, я не уверен, что это технически возможно. .should ожидает блок, который выполняется до и после лямбда. Во всяком случае, насколько мне известно, rspec не поддерживает это (и imho с полным основанием).

Ответ 3

Недавно я столкнулся с этой проблемой при переносе некоторых тестов request на feature тестовый формат для Capybara 2.1 и переключении синтаксиса тестирования с should на основе expect. Чтобы использовать исходный вопрос в качестве примера, у меня был код вроде:

subject { -> { post("/api/users", parameters) } }
it { should change(User,:count).by(1) }
it { should_not change(ActionMailer::Base, :deliveries) }

Приведение этого значения в синтаксис expect в тесте scenario представило некоторые проблемы и дало эту (рабочую) clunkiness (извините, не большой поклонник явно вложенных lambda s/expect s):

expect(-> { expect(post("/api/users", parameters)).to change(User,:count).by(1) }
).to_not change(ActionMailer::Base, :deliveries)

Есть несколько отличных решений этой проблемы в этом потоке StackOverflow, который я пробовал и добился успеха, но то, что я закончил, просто немного изменило исходный формат и разделить каждое утверждение на свой собственный scenario; что-то вроде:

feature "Add users via API" do
  given(:posting_parameters_to_api) { -> { post("/api/users", parameters) } }

  scenario "foo" do
    expect(posting_parameters_to_api).to change(User,:count).by(1)
  end

  scenario "bar" do
    expect(posting_parameters_to_api).to_not change(ActionMailer::Base, 
                                                    :deliveries)
  end
end

Более подробный, чем исходный request spec, но по сути работает таким же образом. Реализация, скорее всего, придет к личным вкусам.