Помощь RSpec + DatabaseCleaner - преждевременное прекращение работы - PullRequest
3 голосов
/ 24 мая 2011

Я немного растерялся из-за того, что RSpec всегда придерживался основанных на xUnit средах тестирования, но я попробую.

Вложенный характер написания спецификаций вызывает у меня некоторые головные боли в отношении того, где я должен выполнять настройку / демонтаж базы данных.

Согласно DatabaseCleaner README:

Spec::Runner.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

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

У меня есть это:

RSpec.configure do |config|
  config.mock_with :rspec

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

Проблема здесь в том, что любые приборы, которые я создаю в блоке subject или let, уже исчезли (из базы данных), когда я пытаюсь использовать их в следующем блоке describe или it.

Например (используя Machinist для создания приборов ... но это не должно быть актуально):

describe User do
  describe "finding with login credentials" do
    let(:user) { User.make(:username => "test", :password => "password") }
    subject { User.get_by_login_credentials!("test", "password") }
    it { should == user }
  end
end

Я борюсь с тем, как я должен вкладывать эти describe и subject и другие блоки, так что, возможно, это моя проблема, но в основном это не удается, потому что, когда он пытается получить пользователя из базы данных, он уже был удален из-за вызова after(:each), предположительно после let?

Ответы [ 2 ]

5 голосов
/ 24 мая 2011

Если вы собираетесь использовать subject и let вместе, вам необходимо понять, как / когда они вызываются.В этом случае subject вызывается перед методом user, сгенерированным let.Проблема не в том, что объект удален из БД до вызова subject, а в том, что он даже не создан в этот момент.

Ваш пример будет работать, если вы используете метод let!, которыйдобавляет хук before, который неявно вызывает метод user перед примером (и, следовательно, до вызова subject).

Тем не менее, я бы рекомендовал вам прекратить бороться и использовать более простые API, чем RSpecуже разоблачает:

describe User do
  it "finds a user with login credentials" do
    user = User.make(:username => "test", :password => "password")
    User.get_by_login_credentials!("test", "password").should eq(user)
  end
end

Это кажется мне намного проще.

3 голосов
/ 24 мая 2011

Вы писали:

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

Правильно, вот как это работает.(И вы не используете приборы в обычном смысле Rails, а фабрики - точно так же, поскольку приборы Rails отстой.)

Каждая отдельная спецификация (то есть каждый it блок) начинается (илидолжен начаться) из первозданной базы данных.В противном случае ваши тесты будут иметь утечку и потерять атомарность.Поэтому вы должны создавать каждую запись, которая вам нужна, в пределах спецификации, в которой она вам нужна (или, как сказал Дэвид, в блоке before, чтобы сократить повторение).

Что касается организации ваших спецификаций ...делай это любым способом, который имеет смысл.Обычно для всего класса будет внешний блок describe с внутренними блоками describe для групп связанного поведения или спецификаций, которые нуждаются в общей настройке.Каждый контекст describe может иметь свои собственные блоки before и after.Они вложены, как и следовало ожидать, поэтому порядок выполнения выглядит примерно так:внешний before
внутренний before
спецификация
внутренний after
внешний after

Если вы хотите увидеть проект с большимколичество спецификаций RSpec и историй о огурцах (хотя для слегка старых версий каждого), посмотрите http://github.com/marnen/quorum2.

...