如何在'context'和'it'块内外调用相同的方法

时间:2017-11-29 06:14:03

标签: ruby rspec

下面是一个简单的rspec示例:

describe 'Emails' do    
  email_ids.each do |email_id|    
    it "should display #{email_id}" do
    end    
  end    
end

def email_ids
  [
    'test1@example.com',
    'test2@example.com',
    'test3@example.com'
  ]
end

上述方法不起作用,因为无法在it块之外访问方法。

请告知如何在email_ids区块之外访问方法it

6 个答案:

答案 0 :(得分:6)

describe创建一个(嵌套的)类并评估该类中的给定块:

describe 'Foo' do     
  p self            #=> RSpec::ExampleGroups::Foo
  describe '' do
    p self          #=> RSpec::ExampleGroups::Foo::Bar
  end
end
另一方面,

it块在相应的类中进行评估。实例:

describe 'Foo' do    
  it 'foo' do 
    p self          #=> #<RSpec::ExampleGroups::Foo ...>
  end
end

如果您通过def email_ids定义方法,它将成为实例方法,因此仅在实例中可用,即在it内。

为了在describe中提供方法,您必须将其定义为类方法,即通过def self.email_ids

describe 'Emails' do
  def self.email_ids
    %w[test1@example.com test2@example.com test3@example.com]
  end

  email_ids.each do |email_id|
    it "should display #{email_id}" do
    end
  end
end

输出:

Emails
  should display test1@example.com
  should display test2@example.com
  should display test3@example.com

您还可以通过将辅助方法放在模块中并使用extend来重复使用辅助方法。有关更多示例,请参阅Define helper methods in a module

答案 1 :(得分:3)

除此之外,我有更好的解决方案。

1.使用'procs'或仅使用如下的局部变量:

email_ids = ->{ %w[test1@example.com test2@example.com test3@example.com] }

email_ids = { %w[test1@example.com test2@example.com test3@example.com] }

proc&amp;的范围local变量将是相同的,但如果你想传递一个参数,那么'procs'是有用的。

2.在module中定义'email_ids'方法,并在module中添加spec,以便该方法可以在'it'块内外访问

module EmailFactoryHelper

  def email_ids
    %w[test1@example.com test2@example.com test3@example.com]
  end

end

包含以下规格:

require 'factories_helper/email_factory_helper'

include EmailFactoryHelper

describe 'Emails' do
  email_ids.call.each do |email_id|
    it "should display #{email_id}" do
      page.should have_content "#{email_id}"
    end
  end
end

输出:

Emails
  should display test1@example.com
  should display test2@example.com
  should display test3@example.com

Finished in 41.56 seconds
3 examples, 0 failures

我更喜欢第2步

答案 2 :(得分:2)

而不是使用proc或范围,  只需在describe block之外使用局部变量。

email_ids = [ 
  'test1@example.com',
  'test2@example.com',
  'test3@example.com'
]
describe 'Emails' do
end

答案 3 :(得分:1)

解决方案是简单地在范围内定义结构,而不是从方法调用返回它:

EMAILS = [
   'test1@example.com',
   'test2@example.com',
   'test3@example.com'
]

EMAILS.each do |email|
  it "should display #{email}" do
  end
end

答案 4 :(得分:0)

由于您在定义方法之前调用了方法,因此无法访问该方法。这个更简单的脚本也有同样的问题:

p email_ids

def email_ids
  [
    'test1@example.com',
    'test2@example.com',
    'test3@example.com'
  ]
end

“未定义的局部变量或方法`email_ids'用于main:Object(NameError)”

您必须在调用方法之前定义方法。您可以将def email_ids移到describe 'Emails'上方来解决此问题。

答案 5 :(得分:0)

@stefan 回答的简短版本: 必须

def self.email_ids
 # stuff
end

def self.method 表示上下文/描述/等;def method 表示它/等)