0

我一直在研究 ruby​​ on rails 教程。我对这些东西完全陌生。我在第 9 章,完全卡住了。我希望有人可以帮助我破译错误消息。到目前为止,我只是搜索它们并弄清楚了,但我认为学习如何破译错误消息以解决问题会更有价值。如果解释起来太长或太麻烦,那么如果没有人愿意接受,我完全理解。我无法在网上找到可以帮助我自己解决这个问题的东西。

这是我目前遇到的错误

1) AuthenticationPages 在登录后尝试访问受保护页面时,为未登录用户使用有效信息授权登录应该呈现所需的受保护页面

 Failure/Error: click_button "Sign in"
 Capybara::ElementNotFound:
   Unable to find button "Sign in"
 # ./spec/requests/authentication_pages_spec.rb:61:in `block (7 levels) in <top (required)>'

2) AuthenticationPages 为非登录用户在访问编辑页面的用户控制器中使用有效信息授权登录

 Failure/Error: it { should have_title('Sign in') }
   expected #has_title?("Sign in") to return true, got false
 # ./spec/requests/authentication_pages_spec.rb:76:in `block (8 levels) in <top (required)>'

3) AuthenticationPages 使用有效信息授权登录用户控制器中的非登录用户作为访问用户#edit 页面的错误用户

 Failure/Error: before { sign_in user, no_capybara: true }
 NoMethodError:
   undefined method `sign_in' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2::Nested_2::Nested_2::Nested_1::Nested_2::Nested_3::Nested_1:0xabbb9e4>
 # ./spec/requests/authentication_pages_spec.rb:87:in `block (8 levels) in <top (required)>'

4) AuthenticationPages 使用用户控制器中未登录用户的有效信息授权登录,因为错误用户向 User#update 操作提交 PATCH 请求

 Failure/Error: before { sign_in user, no_capybara: true }
 NoMethodError:
   undefined method `sign_in' for #<RSpec::Core::ExampleGroup::Nested_2::Nested_2::Nested_2::Nested_2::Nested_1::Nested_2::Nested_3::Nested_2:0xa82d354>
 # ./spec/requests/authentication_pages_spec.rb:87:in `block (8 levels) in <top (required)>'

6.6 秒内完成 65 个示例,4 次失败

失败的例子:

rspec ./spec/requests/authentication_pages_spec.rb:66 # AuthenticationPages 在登录后尝试访问受保护页面时,使用有效信息授权非登录用户登录应该呈现所需的受保护页面

rspec ./spec/requests/authentication_pages_spec.rb:76 # AuthenticationPages 使用有效信息登录用户控制器中访问编辑页面的非登录用户授权

rspec ./spec/requests/authentication_pages_spec.rb:91 # AuthenticationPages 使用有效信息登录用户控制器中的非登录用户作为访问用户的错误用户#edit 页面

rspec ./spec/requests/authentication_pages_spec.rb:96 # AuthenticationPages 使用有效信息登录用户控制器中的未登录用户作为错误用户向 User#update 操作提交 PATCH 请求

authentication_pages_spec.rb

require 'spec_helper'

describe "AuthenticationPages" do


subject { page }


describe "signin page" do
    before { visit signin_path }

    it { should have_content('Sign in') }
    it { should have_title('Sign in') }
end

describe "signin" do
    before { visit signin_path }

    describe "with invalid information" do
        before { click_button "Sign in" }

        it { should have_title('Sign in') }
        it { should have_selector('div.alert.alert-error', text: 'Invalid') }

        describe "after visiting another page" do
            before { click_link "Home" }
            it { should_not have_selector('div.alert.alert-error', text: 'Invalid') }
        end
    end

    describe "with valid information" do
        let(:user) { FactoryGirl.create(:user) }

        before do
            fill_in "Email",     with: user.email.upcase
            fill_in "Password",  with: user.password
            click_button "Sign in"
        end

        it { should have_title(user.name) }
        it { should have_link('Profile',     href: user_path(user)) }
        it { should have_link('Settings',    href: edit_user_path(user)) }
        it { should have_link('Sign out',    href: signout_path) }
        it { should_not have_link('Sign in', href: signin_path) }

        describe "followed by signout" do
            before { click_link "Sign out" }
            it { should have_link('Sign in') }
        end

        describe "authorization" do

            describe "for non-signed-in users" do
                let(:user) { FactoryGirl.create(:user) }

                describe "when attempting to visit a protected page" do
                    before do
                        visit edit_user_path(user)
                        fill_in "Email",    with: user.email
                        fill_in "Password", with: user.password
                        click_button "Sign in"
                    end

                    describe "after signing in" do

                        it "should render the desired protected page" do
                            expect(page).to have_title('Edit user')
                        end
                    end
                end

                describe "in the Users controller" do

                    describe "visiting the edit page" do
                        before { visit edit_user_path(user) }
                        it { should have_title('Sign in') }
                    end

                    describe "submitting to the update action" do
                        before { patch user_path(user) }
                        specify { expect(response).to redirect_to(signin_path) }
                    end

                    describe "as wrong user" do
                        let(:user) { FactoryGirl.create(:user) }
                        let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
                        before { sign_in user, no_capybara: true }

                        describe "visiting Users#edit page" do
                            before { visit edit_user_path(wrong_user) }
                            it { should_not have_title(full_title('Edit user')) }
                        end

                        describe "submitting a PATCH request to the User#update action" do
                            before { patch user_path(wrong_user) }
                            specify { expect(response).to redirect_to(root_url) }
                        end
                    end
                end
            end
        end
    end
  end
 end

user_pages_spec.rb

      require 'spec_helper'

 describe "User pages" do

subject { page }

describe "signup page" do
before { visit signup_path }

it { should have_content('Sign up') }
 it { should have_title(full_title('Sign up')) }
end

describe "signup" do

before { visit signup_path }

let(:submit) { "Create my account" }

describe "with invalid information" do
  it "should not create a user" do
    expect { click_button submit }.not_to change(User, :count)
  end

  describe "after submission" do
    before { click_button submit }
    it { should have_title('Sign up') }
    it { should have_content('error') }
  end


  describe "with valid information" do
    before do
      fill_in "Name",  with: "Example User"
      fill_in "Email",with: "user@example.com"
      fill_in "Password",  with: "foobar"
      fill_in "Confirmation", with: "foobar"
    end

    it "should create a new user" do
      expect { click_button submit }.to change(User, :count).by(1)
    end

    describe "after saving the user" do
      before { click_button submit }
      let(:user) { User.find_by(email: 'user@example.com') }

      it { should have_title(user.name) }
      it { should have_selector('div.alert.alert-success', text: 'Welcome') }
    end

    it "should create a user" do
      expect { click_button submit }.to change(User, :count).by(1)
    end

    describe "edit" do
      let(:user) {FactoryGirl.create(:user) }
      before do
        sign_in user
        visit edit_user_path(user)
      end

      describe "page" do
        it { should have_content("Update your profile") }
        it { should have_title("Edit user") }
        it { should have_link('change', href: 'http://gravatar.com/emails') }
      end

      describe "with invalid information" do
        before { click_button "Save changes" }

        it { should have_content('error') }
      end

      describe "with valid information" do
        let(:new_name) { "New Name" }
        let(:new_email) { "new@example.com" }
        before do
          fill_in "Name",             with: new_name
          fill_in "Email",            with: new_email
          fill_in "Password",         with: user.password
          fill_in "Confirm Password", with: user.password
          click_button "Save changes"
        end

        it { should have_title(new_name) }
        it { should have_selector('div.alert.alert-success') }
        it { should have_link('Sign out', href: signout_path) }
        specify { expect(user.reload.name).to eq new_name }
        specify { expect(user.reload.email).to eq new_email }
      end
    end
  end
     end
  end
 end

我特别好奇“in 'block(7 levels)in”是什么意思。该页面上的级别是什么,还是指的是其他东西?“块”指的是什么?

我似乎也无法理解我得到的水豚错误。它出现在第 8 章,消失了,现在又回来了。当我把它打开时,这个按钮就在页面上,所以我猜水豚找不到它。谁能解释它是如何工作的?

“嵌套”指的是什么?

有谁知道一个很好的网站可以打破这个?我很乐意自己做这项工作,但我找不到。我真的很想自己破译这个,而不是仅仅搜索它并希望答案在某个地方,或者不得不一直依赖其他人来解释它。

非常感谢您的时间和任何帮助。

4

2 回答 2

1

回复:sign_in——sign_in 函数被添加到 spec/support/utilities.rb 的第 9.1.1 节,清单 9.6(在 Rails 4 版本的书中)。

我得到了同样的错误,因为我在实用程序.rb 中的函数是没有下划线的“登录”。一旦我添加了下划线(并更改了对相同函数的其他引用以匹配),测试变为绿色。

于 2013-08-14T04:10:09.063 回答
1

现在是我过度简化时 Stack Overflow 的时候了。(Google 'ruby block' 可以阅读更多关于此的内容。)Ruby 中的块是一堆代码,它们像参数一样传递给方法。例如,

[1,2,3].each{|n| puts n * n }

each是方法(在数组 [1,2,3] 上调用),括号中的所有内容都是块。该方法的each工作方式是,它获取调用它的可枚举 ([1,2,3]) 中的每个元素,并一次将一个元素生成给代码块:

|the first element is 1| puts 1 * 1
|next is 2| puts 2 * 2
|etc| puts 3 * 3

也可以在 之间写入块do...end。如果您可以将块放在一行上,Ruby 的方法是使用括号,do...end否则 - 这就是您在规范中使用它的方式。在您的规范中有一个do和一个匹配的任何地方end都是一个块,一个嵌套在另一个块中。这些方法更难注意到,因为 RSpec 使它看起来像自然语言,但每次编写describeit在一行的开头都是一个方法调用。(letbeforesubjectexpect就此而言,在您的规范中使用单行块调用它们也是如此。)

因此消息“块(7 级)”意味着您的错误嵌套在这么多块中:

describe "AuthenticationPages" do #starts the first block
  ...
  describe "signup" do #starts the second

等等。

现在,您的错误消息。第一个和第二个基本上告诉你同样的事情——你访问edit_user_path(user)了,你在页面标题中看不到“登录”按钮或“登录”。检查 log/test.log 文件 - 当您访问该页面时会发生什么?它是重定向到登录页面吗?应该是,但好像不是。

其他两个错误消息说的完全一样——规范不知道是什么sign_in意思。您需要在 RSpec 可以找到的某个地方定义一个具有该名称的方法 - 在规范本身中,或者在require规范顶部的 spec_helper 文件中,或者在本身require位于 spec_helper 中的某个文件中。

最后,我认为 Hartl 是对的——你尽你所能地在谷歌上搜索错误消息和堆栈跟踪,问你什么时候找不到你要找的东西,随着时间的推移,你会更好地自己解决问题。

于 2013-08-12T13:11:27.483 回答