2017-12-21 5 views
0

既存のRubyのコード:rspecテストケースを書くときにrubyメソッドのローカル変数を上書きする方法は?

def book_details 
    book_count = Book.count 
    while (book_count > 1) 
    # Do something 
    end 
end 

私はbook_details機能でbook_count値を設定し、RSpecのテストケースを書きたいです。出来ますか?はいの場合、どうですか?

it 'Should return 1 book details only' do 
    allow(Model).to receive(book_count).and_return(1) 
    # Do something 
end 

しかし、これは#

+4

は 'てみ許可(書籍)を受信.TO(::数)あなたのコードは、データベースと対話しているので、あなたのテストは、コードが対話するために、実際のレコードを作成する必要があり.and_return(1)' 。 – ndn

+2

実装の内部(プライベート関数、ローカル変数などを含みますが、これに限定されません)をテストしている場合は、間違っているので、設計全体を確認する必要があります。ここでは、適切なテストは次のようになると考えています。1. _single_ 'Book'インスタンスを作成してテストします。 2. 2つの 'Book'インスタンスを作成してテストします。 – mudasobwa

+0

ありがとう@ndn - それは宝石のように動作します。 –

答えて

0

のためのRubyで= 1000 book_countがあったとしましょう「ローカル変数やメソッド `book_countを未定義」というエラーを与えている:

はこれまでのところ、私がしようとしたことはありますあなたはRSpecの持つ10として、それをリセットすると、コードは、その後、下記大丈夫です:

allow(Book).to receive(:count).and_return(10) 

以上はRSpecの中にあなたの期待どおりのカウントを与えるだろう。

また、あなたのrspec contextsと具体的に、rspecmethodsため、ないlocal variablesのために書かれています。 したがって、テストメソッドの期待値はrspecです。

class Book 

    def book_details 
    book_count = Book.count 
    while (book_count > 1) 
     puts 'Book name' 
    end 
    end 

end 

describe 'Books' do 

    describe '#book_details' do 

    context 'when Books are less than one' do 

     it 'should not return book details' do 
     book_details.should eq 0 
     book_details.should_not eq 'Book name' 
     end 

    end 

    context 'when Books are more than one' do 

     before do 
     FactoryGirl.create(:book) 
     end 

     it 'should return book details' do 
     book_details.should_not eq 0 
     book_details.should eq 'Book name' 
     end 

    end 

    end 

end 
0

答え、基本的には、次のとおりです:しないでください

以下はあなたのためのシンプルなmethodrspec例です。

メソッドの途中で変数をオーバーライドする必要があると感じたら、間違っています。このメソッドはあまりにも多くの責任を負うため、分割する必要があります。ここにあなたのケースでは

、テスト作業を取得する一つの簡単な方法は、次のようになります。

allow(Book).to receive(:count).once.and_return(1) 

それとも、少しクリーナーアプローチは、あなただけですので、新しいメソッドにそのコールを抽出することですそのあなたの「自分」の行動をスタブ - のようなもの:

class Foo 
    def book_details 
    while (book_count > 1) 
     # Do something 
    end 
    end 

    def book_count 
    Book.count 
    end 
end 

# In your test: 
let(:foo) { Foo.new } 
allow(foo).to receive(:book_count).once.and_return(1) 

を...しかし、実際には、あなたが本当にが正しくメソッドをテストするために、理想的には、ここで何をやるべきこと、で何かを嘲笑ないことであろうすべて!

# Using FactoryBot, for example: 
let!(:books) { create_list(:book, 5) } 
+0

私はメソッドにlimit = 25という変数がある場合、テストケースでは1だけ必要です。したがって、制限を1に設定する必要があります。 –

+0

単純な変数としてしないでください。あなたの設定値を使用する必要があるように聞こえますが、これはRails環境によって異なります。基本的な考え方は 'book_count = Rails.env.test? 1:25' - これらすべての条件付きでコードベースを捨てることは望ましくないので、 'book_count = CONFIG_VALUES.fetch(:book_count、25)'の行に沿って何かにリファクタリングする必要があります。 –

+0

このような「設定ファイル」を実装する方法はたくさんあります(たとえば、実行時に複数のサーバーに変更するために、分離されたサービスが必要な場合など)。たとえば、[this gem](https://github.com/railsconfig/config)は、かなり簡単な実装を提供します。 –

0
Book.stub(:count).and_return(10) 
+2

これは質問に対する答えを提供しません。十分な[評判](https://stackoverflow.com/help/whats-reputation)があれば、[投稿にコメントする]ことができます(https://stackoverflow.com/help/privileges/comment)。代わりに、[質問者からの明確化を必要としない回答を提供する](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-c​​an- i-do-代わりに)。 - [レビューから](/レビュー/低品質の投稿/ 18329032) – Sree

関連する問題