Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Devise &引用;找不到#<;的有效映射;用户…>&引用;仅在第二次和连续测试中_Devise_Integration Testing_Rspec2_Factory Bot - Fatal编程技术网

Devise &引用;找不到#<;的有效映射;用户…>&引用;仅在第二次和连续测试中

Devise &引用;找不到#<;的有效映射;用户…>&引用;仅在第二次和连续测试中,devise,integration-testing,rspec2,factory-bot,Devise,Integration Testing,Rspec2,Factory Bot,我正在尝试编写一个请求测试,该测试断言应用程序布局上会显示正确的链接,这取决于用户是登录还是注销。FWIW,我在用Desive做认证 这是我的规格: require 'spec_helper' require 'devise/test_helpers' describe "Layout Links" do context "the home page" do context "session controls" do context "for an authentica

我正在尝试编写一个请求测试,该测试断言应用程序布局上会显示正确的链接,这取决于用户是登录还是注销。FWIW,我在用Desive做认证

这是我的规格:

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, ...>

现在,考虑下面的集成测试< /P>

# 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'/'
位注释掉或替换为其他任何内容(或完全没有),测试都可以正常运行


因此,我不知道这是一个工厂女孩问题(我倾向于怀疑它,因为我可以在其他地方使用用户工厂w/o问题)还是一个设计问题(我在应用程序中设置gem后开始出现这些错误,但我也只有一个其他的请求测试,它确实工作正常,但现在出现了AssociationTypeMismatch错误;correlation)≠ 因果关系…)或RSpec问题或其他一些奇怪的边缘案例gem冲突。

我知道这是一条老线索,但我想知道其他人遇到这个问题的答案。不知道我在哪里读到这篇文章,但道具给在另一个论坛上发布这篇文章的人

长话短说,Desive测试助手不能很好地处理集成测试

因此,从规范本身中删除designe::TestHelpers(一些人使用include,其他人使用require'designe/TestHelpers)的所有引用

然后在等级库辅助文件中添加:

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller
end
感谢:

Desive使用类和路由之间的映射,因此,当工厂构建的对象在控制台重新加载或类重新定义后通过Desive时,它将失败

将其放入初始值设定项或application.rb中

ActionDispatch::Callbacks.after do
  # Reload the factories
  return unless (Rails.env.development? || Rails.env.test?)

  unless FactoryGirl.factories.blank? # first init will load factories, this should only run on subsequent reloads
    FactoryGirl.factories.clear
    FactoryGirl.find_definitions
  end
end

Halfnelson的解决方案对我也很有效,但因为我使用的是而不是FactoryGirl,所以我需要做一些调整。以下是我放入初始值设定项的代码:

if Rails.env.development? || Rails.env.test?
  ActionDispatch::Callbacks.after do
    Fabrication.clear_definitions
    Rails.logger.debug 'Reloading fabricators'
  end
end

对于未来的读者:我收到了同样的错误,但原因不同

我们的应用程序有多个用户模型,其中一个来自另一个

为方便起见:

class SimpleUser

class User < SimpleUser
类SimpleUser
类用户
在我的控制器中,我使用了对SimpleUser(父类)的引用,但Desive被配置为使用User(子类)

调用designe::Mapping.find_scope期间!是的,是吗?与对象引用和配置的类进行比较

由于我的引用是一个SimpleUser,并且配置的类是User,那么.u是一个吗?失败,因为比较询问父类是否为?子类,这总是错误的


希望这对其他人有所帮助。

我的routes文件中出现了这个错误,因为我有一个API端点,我想让用户从中重置密码,但我想让用户在web视图上实际更改密码,而该视图在
/API
下没有名称空间

这就是我如何修复路线以使其正常工作:

CoolApp::Application.routes.draw do
  namespace :api, defaults: { format: :json } do
    devise_scope :users do
      post 'users/passwords', to: 'passwords#create'
    end

    resources :users, only: [:create, :update]
  end

  devise_for :users

  root to: 'high_voltage/pages#show', id: 'home'
end

为了防止其他人遇到这种情况,出于与我相同的原因-在更改一些配置文件后,我在基本上所有的测试上都遇到了相同的问题-结果证明,这是由于在我意外运行测试时,
RAILS_ENV
被设置为
development
。在添加特定于测试的rails初始值设定项之前,可能值得检查:-)

将此行添加到您的路由中。rb

#设计路线
为:用户或自定义模型的名称设计

在我的案例中,这是Devis的
确认问题方法。因此,不要这样做(
Minitest::Test
code):

我已经这样做了:

setup do
  @admin = create(:admin)
  @admin.confirm!
end

它起作用了:)

我以前曾以测试用户的身份登录过我的一个应用程序,并进行过一些测试上传和测试发布,我也经历过这种情况。然后,我删除了该测试用户,当我尝试再次与同一测试用户注册时,显示消息“找不到有效的nil映射”。我所做的是删除我作为测试用户所做的所有测试上传和测试帖子。然后我再次尝试注册,结果成功了。通过这种方式,一种更快更简单的删除内容的方法是使用。

我发现,即使用户没有在任何测试用例中实际使用,也会发生这种情况。我正在发布一个更新,因为它太大了,无法在评论表单中发布。我在Desive邮件组中发现了一个讨论相同问题的帖子,但到目前为止也没有答案。正如我在上面的OP中所指出的,这只适用于控制器测试,而不是我尝试的请求测试。你是说你根本不能在集成测试中使用Desive,只能在控制器测试中使用吗?那么,你对这个问题的解决方法是什么?如果你看到的错误和我一样,请确保你使用的类与Desive配置使用的类相同(或者子类也可以工作)。在我的案例中,错误是我试图使用Devise配置为使用的类的父类。有时可能需要使用
ActionDispatch::Callbacks。在
之前,我的案例:
setup do
  @admin = create(:admin).confirm!
end
setup do
  @admin = create(:admin)
  @admin.confirm!
end