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

Спецификация атрибутов синтаксиса и идентификатора RSpec "Ожидание"

У этого должен быть легкий ответ, но я изо всех сил пытаюсь его найти (проверил документацию RSpec, EverydayRails Testing с RSpec, результаты Google). В моих спецификациях моделей я хотел бы включить основные спецификации атрибутов следующим образом:

describe Foo do
  describe "basic attributes" do
    before { @foo = create(:foo) }
    subject { @foo }

    it { should be_valid }
    it { should respond_to(:color) }
    it { should respond_to(:height) }
    it { should respond_to(:some_other_attribute) }
    it { should respond_to(:you_get_the_idea) }
    ...

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

Я включил синтаксис expect во все другие спецификации, и мне нравится, как он читает, но как его использовать здесь? Один из вариантов может быть

expect(@foo).to respond_to(:color)

И еще может быть

expect(it).to respond_to(:color)

Первое включает дублирование, которое избегается синтаксисом should, но последнее выглядит мне странным (это может быть только я).

Я понимаю, что этот вопрос связан скорее с стилем, чем с функциональностью *, но мы, разработчики Ruby, добросовестно относимся к стилю, и я хочу придерживаться стандартных практик и иметь читаемый, идиоматический код. Любая помощь приветствуется. Спасибо.

ОБНОВЛЕНИЕ: Между прочим, ни один из моих предложенных вариантов не работает. Они оба бросают ошибки undefined method 'expect'. Теперь я действительно смущен!

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

4/2015 UPDATE

rspec > 3.0 добавил еще один способ обращения с ними, и похоже, что rspec ~> 4.0 покончит с синтаксисом should. Пер Мирон Мастера:

Некоторые пользователи выразили путаницу в отношении того, как это должно относиться к синтаксису ожидания, и если вы можете продолжать его использовать. Он будет по-прежнему доступен в RSpec 3 (опять же, независимо от конфигурации синтаксиса), но мы также добавили альтернативный API, который немного согласуется с синтаксисом ожидания:

describe Post do
  it { is_expected.to allow_mass_assignment_of(:title) }
end

is_expected определяется очень просто, как ожидание (субъект), а также поддерживает отрицательные ожидания через is_expected.not_to matcher. [...]
В RSpec 3 мы сохранили синтаксис if, и он доступен по умолчанию, но вы получите предупреждение об устаревании, если вы его используете без явного его включения. Это проложит путь для его отключения по умолчанию (или потенциально извлеченного в отдельный камень) в RSpec 4, при этом минимизируя путаницу для новичков, прибывающих в RSpec через старый учебник.

4b9b3361

Ответ 1

Майрон Марстон, один из основных коммиттеров RSpec, объясняет здесь, что вы все равно должны использовать

it { should be_cool }

Если вы отключили синтаксис should, он предлагает решение для псевдонима expect_it - it:

RSpec.configure do |c|
  c.alias_example_to :expect_it
end

RSpec::Core::MemoizedHelpers.module_eval do
  alias to should
  alias to_not should_not
end

При этом вы можете записать это как:

describe User do
  expect_it { to be_valid }
end

Ответ 2

Я не думаю, что есть правильный ответ на этот вопрос, но я недавно переписывал свои тестовые классы, чтобы отойти от should и использовать синтаксис expect исключительно, поэтому я брошу свои два цента Я решил переписать много, потому что Майрон Марстон, сопровождающий RSpec, написал:

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

Он также прокомментировал:

Мы не планируем снимать "should"... но ожидаем, что будет меньше ошибок, и это синтаксис, который я бы рекомендовал для новых проектов.

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

describe Foo do
  let(:foo) { create(:foo) }
  subject { foo }
  describe "model attributes" do
    it { should be_valid }
    it { should respond_to(:color) }
    it { should respond_to(:height) }
    it { should respond_to(:some_other_attribute) }
    it { should respond_to(:you_get_the_idea) }
  end
  # ...
end

Теперь я буду писать так:

describe Foo do
  let(:foo) { create(:foo) }
  specify "model attributes" do
    expect(foo).to be_valid
    expect(foo).to respond_to(:color)
    expect(foo).to respond_to(:height)
    expect(foo).to respond_to(:some_other_attribute)
    expect(foo).to respond_to(:you_get_the_idea)
  end
  # ...
end

Мое мнение состоит в том, что ссылка foo непосредственно на expect(foo).to respond_to(:color) является таким же "дублированием", что и косвенное использование subject с помощью it, поэтому я не слишком поэтапно об этом, и я согреваю как обычно читаются спецификации expect. Но, в конечном счете, я думаю, что это сводится к тому, чтобы быть вопросом предпочтительного стиля письма.