为什么在Ruby on Rails中使用setup方法进行测试套件?

时间:2016-08-02 23:45:13

标签: ruby-on-rails ruby

我正在使用railstutorial.org,在我们的第一个测试套件中,我们在setup方法中设置了一个实例变量。

require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | #{@base_title}"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | #{@base_title}"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | #{@base_title}"
  end
end

为什么我们这样做而不是直接将其定义为实例变量?

1 个答案:

答案 0 :(得分:1)

您将其定义为实例变量。运行测试时,类(StaticPagesControllerTest实例化,并在该实例上调用setup函数,而不是在类上调用。如果您尝试执行以下操作,则会定义无法从实例访问的类级别实例变量:

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  @base_title = "Ruby on Rails Tutorial Sample App"

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | #{@base_title}" # XXX not defined on instance
  end
...

有关差异的一种解释,请参阅this page

您可以使用类变量(@@base_title),但这可能会在以后产生令人惊讶的后果,例如:如果你想把测试子类化。

这是一个快速演示:

class First
  @a = 'hoge'
  @@b = 'hoge'

  def initialize
    @c = 'hoge'
  end

  def give_me_a
    @a
  end

  def give_me_b
    @@b
  end

  def give_me_c
    @c
  end
end

f = First.new
# => #<First:0x007fb81607fcd0>
f.give_me_a
# => nil
f.give_me_b
# => "hoge"
f.give_me_c
# => "hoge"