рельсы для RSpec прежде всего против перед каждой



contest_entry_spec.РБ



    require 'spec_helper'

describe ContestEntry do

before(:all) do
@admission=Factory(:project_admission)
@project=Factory(:project_started, :project_type => @admission.project_type)
@creative=Factory(:approved_creative, :creative_category => @admission.creative_category)
@contest_entry=Factory(:contest_entry, :design_file_name => 'bla bla bla', :owner => @creative, :project => @project)
end

context 'non-specific tests' do
subject { @contest_entry }
it { should belong_to(:owner).class_name('User') }
it { should belong_to(:project) }
it { should have_many(:entry_comments) }

it { should validate_presence_of(:owner) }
it { should validate_presence_of(:project) }
it { should validate_presence_of(:entry_no) }
it { should validate_presence_of(:title) }

end
end


когда я запускаю эти тесты, все в порядке, но если я изменю before(:all) на before(:each), каждый тест будет провален.Я не знаю, почему это происходит?



ошибка



 Failure/Error: @contest_entry=Factory(:contest_entry, :design_file_name => 'bla bla bla', :owner => @creative, :project => @project)
ActiveRecord::RecordInvalid:
Validation Failed: User is not allowed for this type of project
624   4  

4 ответов:

before(:all) запускает блок один раз перед запуском всех примеров.

before(:each) запускает блок один раз перед каждой из ваших спецификаций в файле

before(:all) устанавливает переменные экземпляра @admission, @project, @creative, @contest_entry один раз перед всеми it блоки выполняются.

, :before(:each) сбрасывает переменные экземпляра в блоке before каждый раз, когда it блок запускается.

его тонкое различие, но важно

снова,

before(:all)
#before block is run
it { should belong_to(:owner).class_name('User') }
it { should belong_to(:project) }
it { should have_many(:entry_comments) }

it { should validate_presence_of(:owner) }
it { should validate_presence_of(:project) }
it { should validate_presence_of(:entry_no) }
it { should validate_presence_of(:title) }

before(:each)
# before block
it { should belong_to(:owner).class_name('User') }
# before block
it { should belong_to(:project) }
# before block
it { should have_many(:entry_comments) }
# before block

# before block
it { should validate_presence_of(:owner) }
# before block
it { should validate_presence_of(:project) }
# before block
it { should validate_presence_of(:entry_no) }
# before block
it { should validate_presence_of(:title) }

важная деталь before :all что это не DB transactional. То есть, что угодно внутри before :all сохраняется в БД и вы должны вручную снести в after :all метод.

последствия означают, что после завершения наборов тестов изменения не будут возвращены для последующих тестов. Это может привести к сложным ошибкам и проблемам с перекрестным загрязнением данных. Если возникает исключение after :all обратного вызова не вызывается.

A быстрый тест, чтобы продемонстрировать:

1. Усеките соответствующую таблицу БД, а затем попробуйте это,

  before :all do
    @user = Fabricate(:user, name: 'Happy Fun Pants')
  end

2. наблюдать за базой данных впоследствии модель остается сохраненной! это. Однако, если в тесте возникнет исключение, этот обратный вызов не произойдет, поскольку поток был прерван!

3. теперь попробуйте это,

  before :each do
    @user = Fabricate(:user, name: 'Happy Fun Pants')
  end

4. теперь в база данных остается лишенной данных после завершения набора тестов. Не очень хорошо с настройками CI / CD.

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

короче, before :each, это, вероятно, то, что вы хотите. Ваши тесты будут работать немного медленнее, но это стоит затрат.

подробности здесь: https://relishapp.com/rspec/rspec-rails/docs/transactions Видеть: Data created in before(:all) are not rolled back

надеюсь, что это поможет еще один усталый путешественник.

before(:all), что гарантирует, что примеры пользователей создаются один раз, перед всеми тестами в блоке. Это оптимизация для скорости.

одна вещь, чтобы отметить, по умолчанию перед использованием перед (: each), также в before(:all) экземпляр контроллера не установлен, поэтому методы контроллера, такие как запрос, не используются.

Comments

    Ничего не найдено.