Rspec и проблема рельсов - PullRequest
       2

Rspec и проблема рельсов

1 голос
/ 28 июля 2011

У меня странная проблема с rspec и rails. Итак, у меня есть модель теста:

require 'spec_helper'

describe User do
  before(:each) do
    @attr = { name: "johnkowalski", fullname: "John Kowalski", 
      email: "kowalski@example.com", password: "foobar" }
  end

  describe "Create a user" do

    it "test1" do
      User.create!(@attr)
    end

    it "test2" do
      User.create!(@attr)
    end

    it "test3" do
      User.create!(@attr)
      @p = { name: "testowy", fullname: "John Kowalski", 
      email: "kowalski@example.com", password: "foobar" }
      a = User.new(@p)
      a.should_not be_valid
    end

    it "test4" do
      User.create!(@attr)
    end
  end
end

Проходит без проблем, но когда я добавляю интеграционный тест, например:

require 'spec_helper'

describe "Users" do
  describe "signup" do
    describe "failure" do
      it "should not make a new user" do
        lambda do
          visit signup_path
          fill_in "Name", with: ""
          fill_in "Full name", with: ""
          fill_in "Email", with: ""
          fill_in "Password", with: ""
          click_button
          response.should render_template("users/new")
          response.should have_selector("div#error_explanation")
        end.should_not change(User, :count)
      end
    end
  end
end

У меня сбои:

Failures:

  1) Users signup failure should not make a new user
     Failure/Error: visit signup_path
     AbstractController::ActionNotFound:
       The action 'new' could not be found for UsersController
     # ./spec/requests/users_spec.rb:8:in `block (5 levels) in <top (required)>'
     # ./spec/requests/users_spec.rb:7:in `block (4 levels) in <top (required)>'

  2) User Create a user test4
     Failure/Error: User.create!(@attr)
     ActiveRecord::RecordInvalid:
       Validation failed: Email has already been taken
     # ./spec/models/user_spec.rb:28:in `block (3 levels) in <top (required)>'

Finished in 0.77216 seconds
5 examples, 2 failures

Первая ошибка очевидна (у меня пустой контроллер), но почему вторая? Также, если я сделаю интеграционный тест, который пройдет, модельный тест также пройдет. Я использую рельсы 3.1.0.rc5 и rspec 2.6.4. Даже когда я комментирую строку a.should_not be_valid, это также работает. Я совсем не понимаю.

EDIT: Я знаю, что это проблема проверки, но почему test4 работает в этом примере:

require 'spec_helper'

describe User do
  before(:each) do
    @attr = { name: "johnkowalski", fullname: "John Kowalski", 
      email: "kowalski@example.com", password: "foobar" }
  end

  describe "Create a user" do

    it "test1" do
      User.create!(@attr)
    end

    it "test2" do
      User.create!(@attr)
    end

    it "test3" do
      User.create!(@attr)
      @p = { name: "testowy", fullname: "John Kowalski", 
      email: "kowalski@example.com", password: "foobar" }
      a = User.new(@p)
      a.should_not be_valid
    end

    it "test4" do
      User.count.should == 0
    end
    it "test5" do
      User.create!(@attr)
    end
  end
end

user.rb:

class User < ActiveRecord::Base
  has_secure_password

  email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :name, presence: true, length: { maximum: 20 },
            uniqueness: { case_sensitive: false }
  validates :fullname, presence: true, length: { maximum: 30 }
  validates :email, format: { with: email_regex },
            uniqueness: { case_sensitive: false }, length: { maximum: 30 }
  validates :password, length: { in: 5..25 }

end

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

 (0.0ms)  RELEASE SAVEPOINT active_record_1
   (0.1ms)  SELECT 1 FROM "users" WHERE LOWER("users"."name") = LOWER('testowy') LIMIT 1
   (0.1ms)  SELECT 1 FROM "users" WHERE LOWER("users"."email") = LOWER('kowalski@example.com') LIMIT 1
   (0.1ms)  SELECT COUNT(*) FROM "users" 
   (0.1ms)  SAVEPOINT active_record_1
   (0.1ms)  SELECT 1 FROM "users" WHERE LOWER("users"."name") = LOWER('johnkowalski') LIMIT 1
   (0.1ms)  SELECT 1 FROM "users" WHERE LOWER("users"."email") = LOWER('kowalski@example.com') LIMIT 1
  SQL (0.3ms)  INSERT INTO "users" ("created_at", "email", "fullname", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?, ?)  [["created_at", Thu, 28 Jul 2011 13:09:48 UTC +00:00], ["email", "kowalski@example.com"], ["fullname", "John Kowalski"], ["name", "johnkowalski"], ["password_digest", "$2a$10$e1.3fifGcs7PALH1o0GQJ.Ny/QxCS9fRxDJ6NemGkwfFJCpsD51vy"], ["updated_at", Thu, 28 Jul 2011 13:09:48 UTC +00:00]]
   (0.0ms)  RELEASE SAVEPOINT active_record_1

Но когда я запустил эти тесты и интеграционные тесты, я нашел это в журнале:

 (0.1ms)  SELECT 1 FROM "users" WHERE LOWER("users"."email") = LOWER('kowalski@example.com') LIMIT 1
   (0.1ms)  SELECT COUNT(*) FROM "users" 
   (0.1ms)  SAVEPOINT active_record_1
   (0.1ms)  SELECT 1 FROM "users" WHERE LOWER("users"."name") = LOWER('johnkowalski') LIMIT 1
  CACHE (0.0ms)  SELECT 1 FROM "users" WHERE LOWER("users"."email") = LOWER('kowalski@example.com') LIMIT 1
   (0.0ms)  ROLLBACK TO SAVEPOINT active_record_1

Таким образом, пользовательский объект извлекается из памяти, а не из базы данных. Но по умолчанию кэширование отключено в тестовой среде, и у меня есть config.action_controller.perform_caching = false в среде / test.rb

Как отключить кеширование в этом случае?

1 Ответ

2 голосов
/ 28 июля 2011

Всегда трудно догадаться, сколько вы знаете о rspec, так что, возможно, все это вам очень известно.

Но: вы уверены, что в вашем spec_helper.rb есть следующая строка:

config.use_transactional_fixtures = true

Это гарантирует, что после каждого теста будут выпущены все созданные модели.Обратите внимание, что все в before(:each) происходит внутри транзакции (и откатывается), а что внутри before(:all) - нет (и должно быть очищено в after(all).

. Итак, есливы используете фиксации транзакций, на самом деле это нормально, что User.count == 0, так как все создания откатываются.

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

Во-вторых, поскольку вы, похоже, проверяете свои валидации, я бы посоветовал взглянуть на musta, которая предлагает хорошие сочетания клавиш.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...