Reputation: 415
Below is a simple rspec example:
describe 'Emails' do
email_ids.each do |email_id|
it "should display #{email_id}" do
end
end
end
def email_ids
[
'[email protected]',
'[email protected]',
'[email protected]'
]
end
The above does not work, as methods are not accessible outside the it
block.
Please advise how to make the method email_ids
accessible outside the it
block.
Upvotes: 3
Views: 1766
Reputation: 1
short version of @stefan's answer: needs to be
def self.email_ids
# stuff
end
(def self.method
for context/describe/etc; def method
for it/etc)
Upvotes: 0
Reputation: 46
Rather than using proc or scopes, Simply use local variables outside describe block.
email_ids = [
'[email protected]',
'[email protected]',
'[email protected]'
]
describe 'Emails' do
end
Upvotes: 2
Reputation: 415
I have better solution for this, than above.
1.using 'procs' or just local variable as below:
email_ids = ->{ %w[[email protected] [email protected] [email protected]] }
email_ids = { %w[[email protected] [email protected] [email protected]] }
Scope of proc
& local
variable will be same, but if you want to pass an argument then 'procs' are useful.
2.Define 'email_ids' method in module
and include that module
in spec
, so that method will be accessible inside and outside the 'it' block
module EmailFactoryHelper
def email_ids
%w[[email protected] [email protected] [email protected]]
end
end
include in specs as below:
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
Output:
Emails
should display [email protected]
should display [email protected]
should display [email protected]
Finished in 41.56 seconds
3 examples, 0 failures
I have preferred step-2
Upvotes: 3
Reputation: 1703
The method wasn't accessible because you called the method before you defined the method. This simpler script has the same problem:
p email_ids
def email_ids
[
'[email protected]',
'[email protected]',
'[email protected]'
]
end
"undefined local variable or method `email_ids' for main:Object (NameError)"
You must define your methods before you call them. You can solve this problem by moving the def email_ids
above the describe 'Emails'
.
Upvotes: 0
Reputation: 114188
describe
creates a (nested) class and evaluates the given block within that class:
describe 'Foo' do
p self #=> RSpec::ExampleGroups::Foo
describe '' do
p self #=> RSpec::ExampleGroups::Foo::Bar
end
end
it
blocks on the other hand are evaluated in the corresponding class' instance:
describe 'Foo' do
it 'foo' do
p self #=> #<RSpec::ExampleGroups::Foo ...>
end
end
If you define a method via def email_ids
, it becomes an instance method and is therefore only available within the instance, i.e. within it
.
In order to make a method available within describe
, you have to define it as a class method, i.e via def self.email_ids
:
describe 'Emails' do
def self.email_ids
%w[[email protected] [email protected] [email protected]]
end
email_ids.each do |email_id|
it "should display #{email_id}" do
end
end
end
Output:
Emails
should display [email protected]
should display [email protected]
should display [email protected]
You can also reuse the helper method across multiple tests by putting it in a module and using extend
. See Define helper methods in a module for more examples.
Upvotes: 8
Reputation: 3610
The solution is to simply define your structure within scope, instead of returning it from a method call:
EMAILS = [
'[email protected]',
'[email protected]',
'[email protected]'
]
EMAILS.each do |email|
it "should display #{email}" do
end
end
Upvotes: 1