как тема работает в rspec в ruby ​​on rails

Недавно я узнал о тесте rspec в rails и по ссылке https://relishapp.com/rspec/rspec-core/v/3-6/docs/subject/explicit-subject, в котором говорилось, что "subject запоминается в примере, но не между примерами" с код ниже:

RSpec.describe Array do
  # This uses a context local variable. As you can see from the
  # specs, it can mutate across examples. Use with caution.
  element_list = [1, 2, 3]

  subject { element_list.pop }

  it "is memoized across calls (i.e. the block is invoked once)" do
    expect {
      3.times { subject }
    }.to change{ element_list }.from([1, 2, 3]).to([1, 2])
    expect(subject).to eq(3)
  end

  it "is not memoized across examples" do
    expect{ subject }.to change{ element_list }.from([1, 2]).to([1])
    expect(subject).to eq(2)
  end
end

Может ли кто-нибудь объяснить мне:

  • почему 3.times { subject выполняется только один раз element_list.pop
  • предложение 'это "не запоминается в примерах"' означало, что element_list по-прежнему [1, 2, 3], но в этом примере это только [1, 2] ?

Спасибо.


person Hung    schedule 28.05.2017    source источник


Ответы (1)


Во-первых, в качестве пояснения, помощник RSpec subject является не чем иным, как частным случаем помощника RSpec let. Использование subject { element_list.pop } эквивалентно let(:subject) { element_list.pop }.

Как и любой другой let, subject оценивается один раз для каждого примера. Если subject имеет значение, это значение возвращается без повторной оценки. Общий термин для этого — «запоминание».

Оператор Ruby ||= делает то же самое. В нем говорится: «Если в этой переменной существует значение, верните значение, в противном случае оцените выражение, присвойте его переменной и верните значение». Вы можете увидеть эту концепцию в действии в консоли на следующем примере:

>> element_list = [1, 2, 3]
>> subject ||= element_list.pop
=> 3
>> element_list
=> [1, 2]
>> subject ||= element_list.pop
=> 3
>> element_list
=> [1, 2]
>> subject
=> 3

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

person moveson    schedule 28.05.2017