Когда вы пишете модульные тесты, часто удобно запускать код установки и удаления до и после ваших тестов. Код настройки — это код, который настраивает или «устанавливает» условия для теста. Разрушающий код выполняет очистку, он гарантирует, что среда находится в согласованном состоянии для последующих тестов.
Вообще говоря, ваши тесты должны быть независимы друг от друга. Когда вы запускаете весь набор тестов, и один из них дает сбой, вы хотите быть уверены, что он потерпел неудачу, потому что в тестируемом коде есть ошибка, а не потому, что предыдущий тест оставил среду в несовместимом состоянии.
Наиболее распространенные хуки, используемые в RSpec — это хуки до и после. Они предоставляют способ определения и запуска кода установки и разрыва, который мы обсуждали выше. Давайте рассмотрим этот пример кода —
class SimpleClass attr_accessor :message def initialize() puts "\nCreating a new instance of the SimpleClass class" @message = 'howdy' end def update_message(new_message) @message = new_message end end describe SimpleClass do before(:each) do @simple_class = SimpleClass.new end it 'should have an initial message' do expect(@simple_class).to_not be_nil @simple_class.message = 'Something else. . .' end it 'should be able to change its message' do @simple_class.update_message('a new message') expect(@simple_class.message).to_not be 'howdy' end end
Когда вы запустите этот код, вы получите следующий вывод:
Creating a new instance of the SimpleClass class . Creating a new instance of the SimpleClass class . Finished in 0.003 seconds (files took 0.11401 seconds to load) 2 examples, 0 failures
Давайте внимательнее посмотрим на то, что происходит. Метод before (: each) — это место, где мы определяем код установки. Когда вы передаете аргумент: each, вы инструктируете метод before запускаться перед каждым примером в вашей группе примеров, т.е. двумя блоками it внутри блока description в приведенном выше коде.
В строке: @simple_class = SimpleClass.new мы создаем новый экземпляр класса SimpleClass и присваиваем его переменной экземпляра объекта. Какой объект вам может быть интересно? RSpec создает специальный класс за кулисами в области блока описания. Это позволяет вам присваивать значения переменным экземпляра этого класса, к которым вы можете обращаться внутри блоков it в ваших примерах. Это также облегчает написание более чистого кода в наших тестах. Если для каждого теста (примера) требуется экземпляр SimpleClass, мы можем поместить этот код в ловушку before и не добавлять его в каждый пример.
Обратите внимание, что строка «Создание нового экземпляра класса SimpleClass» записывается в консоль дважды, это показывает, что до вызова ловушки в каждом из блоков it .
Как мы уже упоминали, RSpec также имеет хук после и оба хука до и после могут принимать: все в качестве аргумента. Хук после будет работать после указанной цели. Цель: all означает, что ловушка будет выполняться до / после всех примеров. Вот простой пример, который иллюстрирует, когда вызывается каждый хук.
describe "Before and after hooks" do before(:each) do puts "Runs before each Example" end after(:each) do puts "Runs after each Example" end before(:all) do puts "Runs before all Examples" end after(:all) do puts "Runs after all Examples" end it 'is the first Example in this spec file' do puts 'Running the first Example' end it 'is the second Example in this spec file' do puts 'Running the second Example' end end
Когда вы запустите приведенный выше код, вы увидите этот вывод —