2017-11-29 1 views
2

は簡単なRSpecの例です:メソッドはitブロック外にアクセスすることはできませんようどのように内側と外側の「コンテキスト」と「それはブロックを同じメソッドを呼び出すには、以下の

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 

は上記、動作しません。

email_idsの方法をitブロックの外に出す方法を教えてください。

答えて

1

procまたはスコープを使用するのではなく、 記述ブロックの外側にあるローカル変数を使用します。

1

溶液の代わりにメソッド呼び出しからそれを返すのは、単に範囲内のあなたの構造を定義することである。

EMAILS = [ 
    '[email protected]', 
    '[email protected]', 
    '[email protected]' 
] 

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

'method'にdoneのような引数を渡したいのであれば、 'procs'はスコープよりも有用です。 – Rhunal

+0

私は同意します。その場合、この解決法は機能しません。あなたの最終目標が何であったかはあなたの質問から明らかではありませんでした。 – David

4

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[[email protected] [email protected] [email protected]] 
    end 

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

出力:

Emails 
    should display [email protected] 
    should display [email protected] 
    should display [email protected] 

ます。また、再利用することができますそれをモジュールに入れ、extendを使用して複数のテストに渡るヘルパーメソッド。より多くの例については、Define helper methods in a moduleを参照してください。

+0

ですが、 'email_ids'クラスのメソッドは 'it'ブロック内でどのようにアクセスできるのでしょうか? – Rhunal

+0

優れた説明と私の答えは私がOPがやろうとしていると信じていたことを達成する別の方法を提供していますが、これは実際の質問に対する正しい解決策です。 – David

+0

@Rhunalあなたはそれが 'it'ブロックの外側でアクセス可能であることを望みました。 – Stefan

3

私はこれよりも上の方が良い解決策を持っています。

email_ids = ->{ %w[[email protected] [email protected] [email protected]] } 

email_ids = { %w[[email protected] [email protected] [email protected]] }

proc & local変数のスコープが同じであることが、あなたは、引数を渡したい場合は、その後「procsのでしょう:以下のように 'procsの' または単にローカル変数を1.using

'は便利です。

2。moduleに「email_ids」メソッドを定義し、specmodule、その方法は、内側と外側にアクセスすることができますので、「それは

module EmailFactoryHelper 

    def email_ids 
    %w[[email protected] [email protected] [email protected]] 
    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 [email protected] 
    should display [email protected] 
    should display [email protected] 

Finished in 41.56 seconds 
3 examples, 0 failures 

私が好まれているステップ-2

+0

配列をprocに置く必要はなく、変数に代入するだけです。 – Stefan

+0

これを変数に代入すると、その変数は 'it'ブロックの外側にアクセスできなくなります。 – Rhunal

+0

'email_ids'にアクセスできない場合は、' email_ids.call'を呼び出せませんでしたか? – Stefan

0

メソッドを定義する前にメソッドを呼び出したため、メソッドにアクセスできませんでした。

p email_ids 

def email_ids 
    [ 
    '[email protected]', 
    '[email protected]', 
    '[email protected]' 
    ] 
end 

「メインのため、未定義のローカル変数やメソッド `email_ids':オブジェクト(NameError)」このシンプルなスクリプトは同じ問題を抱えている、あなたがそれらを呼び出す前に、

あなたのメソッドを定義する必要があります。この問題を解決するには、def email_idsdescribe 'Emails'より上に移動します。

関連する問題