RSpec - 依赖对象

时间:2017-06-04 06:48:42

标签: ruby-on-rails rspec

我很擅长使用RSpec进行测试,并且已经解决了这个问题。

我为用户删除了他们的帐户进行了以下测试。

require 'rails_helper'

feature 'delete account' do
  let!(:user) {create :user, :basic}

  scenario 'successfully' do

    login_as(user)
    visit dashboard_path
    click_link 'Settings'
    click_link 'Cancel my account'

    expect(page).to have_content("Your account has been cancelled.")
  end
end

运行测试时,出现以下错误;

1) delete account successfully
 Failure/Error: <%= account.radio_button :plan_id, @plan.id, data: { name: @plan.name, amount: @plan.amount}, checked: true, class: 'hidden' %>

 ActionView::Template::Error:
   undefined method `id' for nil:NilClass

这是控制器代码。当测试点击“设置”时,将显示展示页面。问题在于没有计划,但它们与我正在测试的内容无关。

def show
  @plan = Plan.find_by(name: 'Premium')
  @subscription_pending_cancel = 
  Account.check_subscription_status(@account)
end

我可以在测试运行之前创建计划,通过测试。

 before do
   Plan.create(name: 'Premium')
 end

然而,随着测试套件的增长,不得不创建这样的对象似乎不可持续 - 特别是在速度和保持测试数据库清洁方面。

问题是 - 是否需要为上述测试创建/持久保存一个真实对象(在我的情况下是一个计划),还是有另一种方法?

1 个答案:

答案 0 :(得分:0)

可以在“现实”的几个层面上进行测试,每个层次都有其目的。

您已编写了一个rspec功能规范。这些属于所谓的“接受”测试类别。

RSpec文档说:

  

功能规范是用于执行功能切片的高级测试   通过申请。他们应该只通过外部驱动应用程序   界面,通常是网页。

这些测试的重点应该是尽可能真实,这也意味着尽可能真实地使用对象。

你的观察是正确的,有很多设置要做这些类型的测试,并且它们确实非常慢得很快。这就是为什么你通常不会写太多这些。

快速测试属于单独的类别。这些被称为“单位”测试。它们的关键是只测试一个类的方法,如果对其他类有任何依赖,你应该将它们存根。

这些是你应该有很多的测试。你应该开车以这样的方式编写这些类,以便你可以轻松地删除所有外部依赖项(例如db)。

这个概念被称为测试金字塔。 https://martinfowler.com/bliki/TestPyramid.html