'未定义的局部变量或方法' for expected预期导出到helper中的方法

时间:2017-08-02 08:50:58

标签: ruby-on-rails rspec capybara pageobjects site-prism

目标:由于验证错误,尝试提交空注册表单失败。期望在场景中作为单线(方法)出现。正在根据它们的位置非常精确地检查错误。我不想使用经典计数,直到这是唯一的方法。

def cant_be_blank_error_is_displayed(number_of_times = 1)
  expect(page).to have_content t('errors.messages.blank'), count: number_of_times
end
require 'rails_helper'
require 'email_helper'

feature 'register organisation', type: :feature, js: true do
  let!(:register_page) { RegisterPage.new }
  let!(:login_page) { LoginPage.new }
  let!(:organisation) { create :organisation, name: 'organisation_name' }
  let!(:owner) { create :user, email: 'user@example.com', role: :owner }
  let(:form) { register_page.register_form }

  before { register_page.load }

  context 'creation fails because' do
    scenario 'mandatory fields were left empty' do
      register_page.submit_empty_form
      all_mandatory_fields_cant_be_blank_error_displayed
    # expect(form).to have_content mail_blank_or_taken_error
    end

    scenario (...)
    end
  end

方式:
1。将特定错误定义为页面中的元素

class RegisterPage < SitePrism::Page
  set_url "/sign_up"
  section :register_form, :xpath, "//*[@id='new_user']" do
    element :email, :xpath, "//*[@id='user_email']"
    (...) # other input fields

# binding.pry confirms they appear on the page
    element :mail_blank_or_taken_error, :xpath, "//*[@id='new_user']/div[2]/span"
    element :blank_password_error, :xpath, "//*[@id='new_user']/div[4]/span"
    element :password_too_short_error, :xpath, "//*[@id='new_user']/div[2]/div[3]/p"
    element :mismatch_error, :xpath, "//*[@id='new_user']/div[2]/div[4]/span"
    element :blank_name_error, :xpath, "//*[@id='new_user']/div[2]/div[5]/span"
    element :name_taken_error, :xpath, "//*[@id='new_user']/div[2]/div[5]"
    element :wrong_format_error, :xpath, "//*[@id='new_user']/div[7]/span
    (...)
  end
end


2。创建error_alerts.rb帮助程序以在一个方法中存储期望

def all_mandatory_fields_cant_be_blank_error_displayed
  [
    mail_blank_or_taken_error,
    blank_password_error,
    signs_limit_error,
    blank_name_error,
    blank_adress_line_error,
    blank_city_error,
    blank_country_error,
    blank_zipcode_error,
    blank_phone_number_error,
    blank_website_error,
  ].each do |validation_errors|
   expect(form).to have_content validation_errors
  end
end

障碍: 错误是默认的轨道错误,所以它们没有被定义为翻译,我在同一个约定中使用了另一个规范,一切都完美无瑕。

示例:

def invalid_email_or_password_error_displayed
  expect(login_page).to have_content t("devise.failure.invalid", authentication_keys: "Email")
end

失败:我收到以下错误。

1#my way - 来自|validation_errors|

的每个对象都出现同样的问题
1) register organisation creation fails because mandatory fields were left empty
     Failure/Error: mail_blank_or_taken_error,

     NameError:
       undefined local variable or method `mail_blank_or_taken_error' for #<RSpec::ExampleGroups::RegisterOrganisation::CreationFailsBecause:0x007fe56b336370>
 # ./spec/support/error_alerts.rb:63:in `all_mandatory_fields_cant_be_blank_error_displayed'
 # ./spec/features/organisation_registration_spec.rb:16:in `block (3 levels) in <top (required)>'

2#Classical expect

  1) register organisation creation fails because mandatory fields were left empty
     Failure/Error: expect(form).to have_content 
mail_blank_or_taken_error

     NameError:
       undefined local variable or method `mail_blank_or_taken_error' for # <RSpec::ExampleGroups::RegisterOrganisation: :CreationFailsBecause:0x007ff02e7b9348>#./spec/features/organisation_registration_spec.rb:17:in `block (3 levels) in <top (required)>'

问题:经过一些修改或唯一的解决方案是使用经典计数方法,我的方法在技术上是否可以实现?可以循环迭代页面的元素吗?这是其类似用法的一个示例,尽管期望是字符串,并且循环本身包含在规范的场景中,而不是在帮助器中导出到外部方法。

scenario "is successful" do
      all_ministry_memberships_page.create_new(ministry, cabinet, minister)
      [
        t("flash.actions.create.notice", resource_name: "Ministry membership"),
        "Ministry " + ministry.name,
        "Cabinet " + cabinet.name,
        "Minister " + minister.name,
        "Start Date " + (cabinet.appointment_date + 2.days).strftime("%Y-%m-%d"),
        "Created At " + ministry_membership.created_at.strftime("%B %0e, %Y %H:%M"),
        "Updated At " + ministry_membership.updated_at.strftime("%B %0e, %Y %H:%M"),
      ].each do |form_input|
        expect(form).to have_content form_input
      end
    end

2 个答案:

答案 0 :(得分:0)

int*

表示&#34;调用方法[ mail_blank_or_taken_error, blank_password_error, ] ,然后调用mail_blank_or_taken_error()并将结果放入数组&#34;。你没有这样的方法,这就是错误信息告诉你的方法。如果你想要那些是字符串,那就把它们作为字符串。

blank_password_error()

[
  "mail_blank_or_taken_error",
  "blank_password_error",
]

答案 1 :(得分:0)

我找到了解决这个问题的方法。

该方法需要正确的参数解析和page_object参考

def all_mandatory_fields_cant_be_blank_error_displayed_in(form)
  [
    form.blank_password_error,
    form.signs_limit_error,
    form.blank_name_error,
    form.blank_adress_line_error,
    form.blank_city_error,
    form.blank_country_error,
    form.blank_zipcode_error,
    form.blank_phone_number_error,
    form.blank_website_error,
  ].each do |validation_error|
    expect(validation_error).to be_present
  end
end