Ruby on rails 在当前用户上调用name方法会导致测试错误(RubyonRails)

Ruby on rails 在当前用户上调用name方法会导致测试错误(RubyonRails),ruby-on-rails,ruby-on-rails-4,railstutorial.org,Ruby On Rails,Ruby On Rails 4,Railstutorial.org,我在MichaelHartl的Rails教程中完成了第11章,之后我开始寻找一种方法来使用添加一些声誉和投票功能到MicroPost 我想在导航栏的一个小框中显示当前用户的声誉(如堆栈溢出)。我可以通过以下方式获得用户名和声誉以显示: <li class="rep_box"><%= current_user.name %> <%= current_user.karma %> </li> 该页面运行良好,正确呈现了用户名和信誉,但

我在MichaelHartl的Rails教程中完成了第11章,之后我开始寻找一种方法来使用添加一些声誉和投票功能到MicroPost

我想在导航栏的一个小框中显示当前用户的声誉(如堆栈溢出)。我可以通过以下方式获得用户名和声誉以显示:

       <li class="rep_box"><%= current_user.name %> <%= current_user.karma %> </li>
  • 该页面运行良好,正确呈现了用户名和信誉,但现在我遇到了几个错误并失败了。如果我删除了上面的代码行,一切都会再次正常工作

    下面是一个错误示例——它们几乎都是一样的:

    >ERROR["test_should_get_home", StaticPagesControllerTest, 2016-04-09 04:36:31 -0400]
     test_should_get_home#StaticPagesControllerTest (1460190991.59s)
    ActionView::Template::Error:         ActionView::Template::Error: undefined method `name' for nil:NilClass
                app/views/layouts/_header.erb:6:in `_app_views_layouts__header_erb__1475229759153232172_2241208160'
                app/views/layouts/application.html.erb:12:in `_app_views_layouts_application_html_erb__4357373253304461109_2216429940'
                test/controllers/static_pages_controller_test.rb:9:in `block in <class:StaticPagesControllerTest>'
            app/views/layouts/_header.erb:6:in `_app_views_layouts__header_erb__1475229759153232172_2241208160'
            app/views/layouts/application.html.erb:12:in `_app_views_layouts_application_html_erb__4357373253304461109_2216429940'
            test/controllers/static_pages_controller_test.rb:9:in `block in <class:StaticPagesControllerTest>'
    
    >错误[“测试应该回家”,StaticPagesControllerTest,2016-04-09 04:36:31-0400]
    测试应返回主页静态页面控制器测试(1460190991.59s)
    ActionView::Template::错误:ActionView::Template::错误:未定义nil:NilClass的方法“name”
    app/views/layouts/_header.erb:6:in`_app\u views\u layouts\u header\u erb\u 1475229759153232172\u 2241208160'
    app/views/layouts/application.html.erb:12:in`_app_views_layouts_application_html_erb__4357373; 4353304461109_2216429940'
    test/controllers/static\u pages\u controller\u test.rb:9:in'block in'
    app/views/layouts/_header.erb:6:in`_app\u views\u layouts\u header\u erb\u 1475229759153232172\u 2241208160'
    app/views/layouts/application.html.erb:12:in`_app_views_layouts_application_html_erb__4357373; 4353304461109_2216429940'
    test/controllers/static\u pages\u controller\u test.rb:9:in'block in'
    

    这意味着当调用
    name
    时,
    current_user
    nil
    。确保在该点正确分配,错误将消失。

    在有
    当前用户之前,您需要
    用户中签名

    你可以这样做:

    let(:curr_user) { User.create(...attrs...) }
    sign_in curr_user
    
    从:

    Desive包括一些功能规格的测试助手。为了 使用它们时,您需要在功能测试中包括designe 将以下内容添加到test/test_helper.rb文件的底部 (请确保将其置于ActiveSupport::TestCase的范围之外 是test/test\u helper.rb中的默认类):

    只需确保在要求之后进行此包含即可 “rspec/rails”指令

    现在,您已经准备好使用sign_in和sign_out方法。这样的 方法具有与控制器中相同的签名:

    sign_in :user, @user   # sign_in(scope, resource) 
    sign_in @user          # sign_in(resource)
    
    sign_out :user         # sign_out(scope) 
    sign_out @user         # sign_out(resource)
    
    否则,
    当前用户
    将正确地成为
    nil
    。如果您希望您的代码能够容忍这种情况,那么您应该在视图中使用类似于
    的内容来保护该位,除非当前用户.nil?
    。我还看到有人创建了一个
    current\u user\u或
    方法来取代他们对
    current\u user
    的使用

    在助手中,他们创建了如下内容:

      def current_or_guest_user
        if current_user
          current_user
        else
          User.new
        end
      end
    
    def current_user
      User.find_by(id: session[:user_id])
    end
    
    编辑:

    在中,它不使用Desive,而是让您创建一个
    当前用户
    方法,如下所示:

      def current_or_guest_user
        if current_user
          current_user
        else
          User.new
        end
      end
    
    def current_user
      User.find_by(id: session[:user_id])
    end
    
    当没有
    会话[:user\u id]
    时,此
    当前用户
    方法将返回
    nil
    。在当前用户不再返回
    nil
    之前,您仍然需要对用户进行身份验证。已经有测试代码在
    test/integration/users\u login\u test.rb
    中进行用户身份验证测试

    因此,在测试中,您需要确保执行类似于
    登录User.find\u by(id:)
    的操作来验证用户。这将确保
    当前用户
    像在正常使用环境中一样执行

    您可以添加一个
    test/support
    目录,并在其中创建
    login\u helpers.rb

    def log_in_with(email,password) do
      get login_path
      post login_path, session: { email: email, password: password }
    end
    
    然后,为了确保这些方法可用,请在
    test/test\u helper.rb中添加:

    Dir[Rails.root.join('test/support/**/*.rb')].each { |f| require f }
    
    现在,在需要经过身份验证的用户的测试中,请执行以下操作:

    log_in_with('a_valid_email', 'its valid password')
    

    我打过电话,零?在当前的_user.name上,返回为false。是测试失败了。@gbutters,请尝试将您的nil检查正确地放在视图中,这样您就知道它在正确的上下文中,例如,
    我尝试了这个方法,但我不确定是为了什么目的。它在测试中输出了一堆额外的信息,比如“cun?:false,cun?:true…”@gbutters,每当它输出
    cun?:true
    ,这意味着
    当前用户
    nil
    ,您将得到未定义的方法错误。因此,您需要找出为什么在这种情况下,
    current\u user
    没有正确设置。在thumbs\u up文档中有一些关于测试的内容:想知道这样做是否可行?那么您使用什么创建
    current\u user
    方法?这不是由ThumbsUp创建的。测试中的那个部分是为了测试ThumbsUp,而不是测试你的应用程序的ThumbsUp实现。你所做的是正确的,你只是缺少一些建立当前用户的东西。我在Rails教程中找到了更多细节,并编辑了我的答案。我将在几分钟内添加更多代码。这个id是否可以在模型用户下的users.yml fixtures文件中声明?是否有人可以通过向test_helper.rb的log_in_as()函数中添加一些内容来验证是否可以修复这个问题?