【问题标题】:Devise User testing with RSpec使用 RSpec 设计用户测试
【发布时间】:2017-01-30 14:45:47
【问题描述】:

我已将 Devise 与我的 RoR 应用程序集成,现在正在尝试测试我的控制器,特别是将我路由到我的 root_url 的控制器。

我已经在 Devise 的页面上使用了这个 HOWTO 来设置我的管理员/用户工厂,但是在我的用户注册过程中还有一个附加组件,它正在创建一个 Company

所以:

User:has_one :company

Company:has_many :users

新用户的流程如下所示:

  1. 用户注册
  2. 用户确认帐户(通过电子邮件)并被重定向到登录页面
  3. 用户登录
  4. 用户填写Company信息并提交
  5. 然后用户被重定向到Pages#home(这是我的root_url

使用 Devise 的 HOWTO,我在 Support 中创建了一个 ControllerHelpers 文件:

module ControllerHelpers
  def login_user
    before(:each) do
      @request.env["devise.mapping"] = Devise.mappings[:user]
      user = FactoryGirl.create(:user)
      user.confirm # or set a confirmed_at inside the factory. Only necessary if you are using the "confirmable" module
      sign_in user
    end
  end
end

我怀疑我的 User Factory 有问题,因为它似乎没有创建 Company,但我对 RSpec 很陌生,我不确定。

FactoryGirl.define do
  factory :user do
    first_name "Test"
    last_name "User"
    full_name "Test User"
    email "test@user.com"
    phone_number "111-222-3333"
    terms_accepted true
    time_zone "Central Time (US & Canada)"
    password "password"
    password_confirmation "password"
    confirmed_at Date.today
    association :company
  end
end

我也有一个company.rb 工厂:

FactoryGirl.define do

  factory :company do
    id 1
    name "ACME Test"
    address_1 "123 Shady Lane."
    address_2 "Suite 400"
    city "Testville"
    state "Test"
    zip_code "12345"
    has_payment_plan false
    stripe_id "cus_34d434343e4e3e3"
    locked false
  end
end

此时我的pages_controller_spec.rb 很简单:

需要'rails_helper'

RSpec.describe PagesController, :type => :controller do

  describe "User: GET #home" do
    login_user

    it "signs in the user" do
      expect(response).to render_template(:home)
    end
  end
end

这会导致以下 RSpec 错误:

1) PagesController User: GET #home signs in the user
 Failure/Error: expect(response).to render_template(:home)
   expecting <"home"> but was a redirect to <http://test.host/companies/new>
 # ./spec/controllers/pages_controller_spec.rb:10:in `block (3 levels) in <top (required)>'

那么,它甚至没有做我测试的render_template 部分?

更新:添加了家庭控制器

controllers/pages_controller#home

def home
    if current_user && current_user.company
      verify_subscription
      get_company_and_locations
      get_network_hosts
      get_network_hosts_at_risk
      @network_hosts_snip = @network_hosts_at_risk.sort_by{ |h| -h.security_percentage }.first(5)
      get_company_issues
      @issues = @issues.sort_by{ |i| -i.cvss_score }.first(5)
      @deferred_issues = @company.deferred_issues.last(5)
      @deferred_hosts = @company.deferred_hosts.last(5)
    else
      redirect_to new_company_path
    end
  end

【问题讨论】:

  • 这不是您主要问题的答案,但仍然...您的公司已创建但未持久保存到数据库。这就是strategy: :build 的目的。因此,要创建您的公司并将其保存到 DB 中,只需将 association :company, strategy: :build 替换为 company。但是,我会尝试找到主要问题的答案。您可以添加您要测试的控制器的home 操作吗?
  • @VAD 刚刚添加了 pages#home 控制器方法
  • 好的,事实证明这可能是您主要问题的答案。现在在user 工厂中进行更正,我建议您必须创建current_user 并且它是company,因此您的home 操作不会继续redirect_to,而是将执行默认render。没有其他东西可以阻止您的测试通过。试试看,如果通过了,我会添加我之前的评论作为答案。
  • @VAD 抱歉,总的来说,我对“测试”还很陌生,所以我并不完全理解我们在这里所做的事情。还有,还是不行……
  • 我们只是为您的用户关联对象company 设置了持久化到数据库中的东西,而不是仅仅在内存中创建。现在出现的错误和以前一样吗?

标签: ruby-on-rails ruby rspec devise


【解决方案1】:

正如我们在聊天中一起发现的那样...您的company 已创建,但并未持久保存到数据库中。这是因为你的工厂里有strategy: :build

strategy: :build 表示您的关联对象将被创建但不会被持久化到数据库。要坚持它,你应该使用strategy: :create。或者在您的用例中,您可以将 association :company, strategy: :build 替换为 company。 FactoryGirl 足够聪明,可以将其识别为必须创建和保持的关联。

你需要在companysubscription之间建立FactoryGirl关联。

【讨论】:

    猜你喜欢
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多