Как тестировать методы класса в RSPEC

Я написал простой метод класса Buy.get_days(string) и пытается протестировать его с различными вводами текстовой строки. Однако я чувствую, что это очень много.

  • Есть ли более сжатый способ проверить следующее?
  • Есть ли эквивалент subject для методов, которые я могу просто продолжать различные параметры и проверить результаты?
  • Есть ли способ избежать ненужного описания на каждом it?

спасибо

 describe Buy do
   describe '.get_days' do
    it 'should get days' do
      Buy.get_days('Includes a 1-weeknight stay for up to 4 people')
      .should == 1
      end
    it 'should get days' do
      Buy.get_days('Includes a 1-night stay in a King Studio Room with stone fireplace')
      .should == 1
    end
    it 'should get days' do
      Buy.get_days('Includes 4 nights/5 days at the Finisterra Hotel for up to two adults and two children (staying in the same room)')
      .should == 4
    end
  end
end

Ответы

Ответ 1

Этот является интересным, хотя, возможно, более тупым способом использования блока "subject" с помощью методов класса.

Изменить: сломанная ссылка, как сообщается архивом Wayback, который, я полагаю, подвержен той же проблеме.

Ответ 2

Для вызова метода нет эквивалента subject, поэтому использование it - это путь сюда. Проблема, которую я вижу с представленным вами кодом, заключается в том, что она фактически не объясняет, для чего вы тестируете. Я бы написал еще что-то вроде:

describe Buy do
  describe '.get_days' do
    it 'should detect hyphenated weeknights' do
      Buy.get_days('Includes a 1-weeknight stay for up to 4 people').should == 1
    end
    it 'should detect hyphenated nights' do
      Buy.get_days('Includes a 1-night stay in a King Studio Room with stone fireplace').should == 1
    end
    it 'should detect first number' do
      Buy.get_days('Includes 4 nights/5 days at the Finisterra Hotel for up to two adults and two children (staying in the same room)').should == 4
    end
  end
end

Я делаю предположения о том, что вы здесь, но, надеюсь, идея понятна. Это также приведет к значительно более эффективному выходу ошибок при неудачной проверке. Надеюсь, это поможет!

Ответ 3

По-видимому, существует метод described_class.

https://www.relishapp.com/rspec/rspec-core/docs/metadata/described-class

Я полагаю, что он более чистый, чем subject.class, поскольку он не вводит другой вызов метода ., что уменьшает читаемость.

Использование described_class или subject.class может быть более DRY, чем явно указывать класс в каждом примере. Но лично я думаю, что не получить подсветку синтаксиса, которая связана с упоминанием имени класса явно как своего рода облом, и я думаю, что он уменьшает читаемость, несмотря на то, что он полностью выигрывает в отделе ремонтопригодности.

Возникает вопрос о наилучшей практике:

Следует ли использовать описанный класс по возможности внутри и вне метода .expect() или только внутри метода expect()?

Ответ 4

Это может быть старый вопрос, но вы всегда можете использовать subject.class для доступа:

describe Buy do
  describe '.get_days' do
    it { expect(subject.class.get_days('Includes a 1-weeknight stay for up to 4 people')).to eq 1 }
  end
end

Ответ 5

Альтернативой использованию subject/it является использование before/specify:

describe '#destroy' do
  context 'with children' do
    before { @parent = FactoryGirl.create(:parent, children: FactoryGirl.create_list(:child, 2) }
    specify { @parent.destroy.should be_false }
  end
end

Это приведет к разумному описанию в формате RSpec -fd:

#destroy
  with children
    should be false