«Не удалось найти действительное сопоставление для # » только во втором и последующих тестах

Я пытаюсь написать тест запроса, который утверждает, что правильные ссылки появляются в макете приложения в зависимости от того, вошел ли пользователь в систему или нет. FWIW, я использую Devise для аутентификации.

Вот моя спецификация:

require 'spec_helper'
require 'devise/test_helpers'

describe "Layout Links" do
  context "the home page" do
    context "session controls" do
      context "for an authenticated user" do
        before do
          # I know these should all operate in isolation, but I
          # want to make sure the user is explicitly logged out
          visit destroy_user_session_path

          @user = Factory(:user, :password => "Asd123", :password_confirmation => "Asd123")
          @user.confirm!

          # I tried adding this per the Devise wiki, but no change
          @request.env["devise.mapping"] = Devise.mappings[:user]

          # Now log a new user in
          visit new_user_session_path
          fill_in "Email",    :with => @user.email
          fill_in "Password", :with => "Asd123"
          click_button "Sign in"
          get '/'
        end

        it "should not have a link to the sign in page" do
          response.should_not have_selector(
            '#session a',
            :href => new_user_session_path
          )
        end

        it "should not have a link to registration page" do
          response.should_not have_selector(
            '#session a',
            :href => new_user_registration_path
          )
        end

        it "should have a link to the edit profile page" do
          response.should have_selector(
            '#session a',
            :content => "My Profile",
            :href => edit_user_registration_path
          )
        end

        it "should have a link to sign out page" do
          response.should have_selector(
            '#session a',
            :content => "Logout",
            :href => destroy_user_session_path
          )
        end
      end # context "for an authenticated user"
    end # context "session controls"
  end
end

Первый тест прошел, но все три последних не прошли с ошибкой

Failure/Error: @user = Factory(:user, :password => "Asd123", :password_confirmation => "Asd123")
  RuntimeError:
    Could not find a valid mapping for #<User id: xxx, ...>

Я искал через вики Devise, группа Google и результаты поиска по причине,но все, что я нахожу, это вопросы без ответа или предложения по установке config.include Devise :: TestHelpers,: type =>: controller , но это относится только к тестам контроллера, а не к тесту запроса.


Обновление

Я провел еще несколько действий по устранению неполадок, и я не могу понять, что в конечном итоге вызывает проблему. Взгляните на следующий код.

Во-первых, для некоторого контекста это объявление фабрики пользователя. Он отлично работает в модульных тестах.

# spec/factories.rb
Factory.define :user do |f|
  f.email { Faker::Internet.email }
  f.email_confirmation { |f| f.email }
  f.password "AbcD3fG"
  f.password_confirmation "AbcD3fG"
  f.remember_me { (Random.new.rand(0..1) == 1) ? true : false }
end

Теперь рассмотрим следующий интеграционный тест

# spec/requests/user_links_spec.rb
require "spec_helper"

describe "User Links" do
  before(:each) do
    # This doesn't trigger the problem
    # @user = nil

    # This doesn't trigger the problem
    # @user = User.new

    # This doesn't trigger the problem
    # @user = User.create(
    #   :email => "foo@bar.co", 
    #   :email_confirmation => "foo@bar.co", 
    #   :password => "asdf1234", 
    #   :password_confirmation => "asdf1234"
    # )

    # This doesn't trigger the problem
    # @user = User.new
    # @user.email = Faker::Internet.email
    # @user.email_confirmation = @user.email
    # @user.password = "AbcD3fG"
    # @user.password_confirmation = "AbcD3fG"
    # @user.remember_me = (Random.new.rand(0..1) == 1) ? true : false
    # @user.save!

    # This triggers the problem!
    @user = Factory(:user)

    # This doesn't trigger the same problem, but it raises a ActiveRecord::AssociationTypeMismatch error instead. Still no idea why. It was working fine before in other request tests.
    # @user = Factory(:brand)
  end

  context "when using `@user = Factory(:user)` in the setup: " do
    2.times do |i|
      it "this should pass on the 1st iteration, but not the 2nd (iteration ##{i+1})" do
        # This doesn't trigger an error
        true.should_not eql(false)
      end

      it "this should pass on the 1st iteration, but trigger the error that causes all successive test cases to fail (iteration ##{i+1})" do
        # Every test case after this will be borken!
        get '/'
      end

      it "this will fail on all iterations (iteration ##{i+1})" do
        # This will now trigger an error
        true.should_not eql(false)
      end
    end
  end
end

. Если мы закомментируем или заменим бит get '/' чем-то еще (или вообще ничем), тесты все работает нормально.

Итак, я не знаю, является ли это проблемой factory_girl (я склонен сомневаться в этом, поскольку я могу использовать фабрики пользователей в другом месте без проблемы) или проблемой Devise (я начал получать эти ошибки после установки этот драгоценный камень в моем приложении, но у меня был только один другой тест запроса, который работал нормально, но теперь я получаю эту ошибку AssociationTypeMismatch; корреляция ≠ причинно-следственная связь ...), или проблема RSpec, или какой-то другой странный конфликт гемов с граничным случаем.

28
задан Chris Bloom 25 June 2011 в 03:39
поделиться