Несколько операторов должны в одном rspec это предложение - плохая идея?

Вот мой тест rspec:

it "can release an idea" do
  james.claim(si_title)
  james.release(si_title)
  james.ideas.size.should eq 0
  si_title.status.should eq "available"
end

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

16
nl ja de

4 ответы

Моя интерпретация этого заключается не столько в том, что должно быть точно одно утверждение/вызов должно для каждой спецификации, но должно быть только один бит поведения, протестированный для каждой спецификации, так например

it 'should do foo and bar' do
  subject.do_foo.should be_true
  subject.do_bar.should be_true
end

это плохо - вы одновременно указываете 2 разных поведения.

с другой стороны, если ваши 2 утверждения просто проверяют разные аспекты одной вещи, тогда я в порядке с этим, например

it 'should return a prime integer' do
  result = subject.do_x
  result.should be_a(Integer)
  result.foo.should be_prime
end

Для меня не было бы лишнего смысла иметь одну спецификацию, которая проверяет, что она возвращает целое число и отдельное, которое возвращает премьер.

Конечно, в этом случае совпадение be_prime может легко выполнить обе эти проверки - возможно, правильное правило состоит в том, что несколько утверждений в порядке, если вы могли бы разумно сократить их до 1 с помощью специального совпадения (действительно ли это действительно стоит зависит от вашей ситуации)

В вашем конкретном случае можно утверждать, что в игре есть два поведения: один изменяет статус, а другой мутирует коллекцию ideas . Я бы пересмотрел ваши спецификации, чтобы сказать, что должен сделать метод выпуска -

it 'should change the status to available'
it 'should remove the idea from the claimants ideas'

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

22
добавлено
Недостаточно ли be_prime? :)
добавлено автор Trejkaz, источник

У меня такая же проблема... Должно быть, каждый должен за него (говорит мой босс), заставляя тестировать время и, как вы сказали, глупо. Тесты требуют хорошего чувства и гибкости, или они могут оказаться в порабощении . Во всяком случае, я согласен с вашим тестом.

3
добавлено

Моя политика заключается в том, чтобы всегда рассматривать множественные утверждения как признак потенциальной проблемы и заслуживать второй мысли, но не обязательно неправильно. Вероятно, 1/3 спецификации, которую я пишу, в конечном итоге имеют несколько утверждений в них по той или иной причине.

Одна из проблем с множественными утверждениями заключается в том, что когда кто-то терпит неудачу, вы не можете видеть, прошел ли другой или нет. Иногда это можно обойти, построив массив результатов и утверждая значение массива.

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

Я думаю, что вы пытаетесь утверждать поведение любого типа james , но тест также зависит от поведения si_title , чтобы рассказать нам, что (через его возможное значение #status ). Вместо этого я обычно делаю si_title test-double и использую #should_receive , чтобы напрямую указывать сообщения, которые он должен ожидать.

2
добавлено

Я думаю, что Фредерик Чунг дал очень хороший ответ (+1), особенно why , но я также хотел бы дать сравнительный бит кода для просмотра, который использует его , позволяет , до и context :

context "Given a si_title" do
  let(:james) { James.new } # or whatever
  before do
    james.claim(si_title)
    james.release(si_title)
  end
  context "That is valid" do
    let(:si_title) { Si_title.new } # or whatever

    describe "James' ideas" do
      subject { james.ideas }
      its(:size) { should == 0 }
      its(:whatever) { should == "Whatever" }
    end
    describe "Si title" do
      subject { si_title }
      its(:status) { should == "available" }
    end
  end
  context "That is invalid" do
    # stuff here
  end
end

Я бы даже пошел дальше и сделал ожидаемые значения let s, а затем сделал примеры shared_example s, чтобы они могли быть использованы для проверки различных аспектов (нулевые аргументы, неверные аргументы, неправильный объект ...), но я считаю, что это гораздо лучший способ рассказать о ваших намерениях и все же сократить любое повторение. Взяв пример из ответа Фредерика:

it 'should return a prime integer' do
  result = subject.do_x
  result.should be_a(Integer)
  result.foo.should be_prime
end

Используя синтаксис RSpec для полного эффекта, вы получите следующее:

  let(:result) { 1 }
  subject{ result }
  its(:do_x) { should be_a(Integer) }
  its(:foo) { should be_prime }

Это означает, что вы можете проверить несколько аспектов предмета.

2
добавлено
pro.ruby
pro.ruby
1 181 участник(ов)

Язык программирования Ruby Additional docs: https://rubyreferences.github.io/rubyref/ Invite: https://telegram.me/joinchat/Be4rsT2NuB3CyJaF26j1kA Кто хочет компилировать: @crystal_ru (его синтаксис основан на Ruby) Участник @proDOT

Ruby, Rails, Hanami | dry-rb
Ruby, Rails, Hanami | dry-rb
1 180 участник(ов)

https://telegram.me/rubyjob - Ruby Job По вопросам - @eugene_shved

Ruby School .us
Ruby School .us
1 045 участник(ов)

Чат-болталка для учеников руби-школы и не только. Правила: https://telegra.ph/Pravila-chata-Rubi-shkoly-03-13

Random Ruby Chat
Random Ruby Chat
589 участник(ов)

Правила публикации вакансий: https://t.me/codenamecrud/60865

Rubyata
Rubyata
333 участник(ов)

Коммюнити Ruby и Ruby On Rails Флуд не приветствуются. Вакансии можно публиковать только и ТОЛЬКО по пятницам с хештегом #вакансия.

Ruby Talks
Ruby Talks
236 участник(ов)

Национальная Флеймотека

RubyRush
RubyRush
189 участник(ов)

rubyrush.ru программирование для самых новичков

Rails Chat
Rails Chat
87 участник(ов)

You are welcome to discuss Ruby On Rails development process and other stuff