0

私はrspec、モック、スタブの初心者です。私はゆっくりと、分離されたテストと一般的なモック/スタブの概念を理解し、理解し始めています。基本的な質問がありますが、コードで簡単に説明できると思います:

class NewsItem < ActiveRecord::Base
  ...
  scope :ordered, order("created_at DESC")
  ...
end

私のモデル テストでは、news_items の順序付きリストを返す動作をテストしたいと考えています。FactoryGirl DB タッチ テストを使用して、次のようにこれを達成します。

# TODO use mocking and stubbing here
it "should have an ordered method to retrieve news items in the descending order" do
  news_item_x = create(:news_item, created_at: DateTime.new(2012,01,01))
  news_item_y= create(:news_item, created_at: DateTime.new(2011,01,01))
  news_item_z= create(:news_item, created_at: DateTime.new(2012,03,01))

  # .all added to avoid comparison failure between groups of NewsItem objects an ActiveRel group.
  expect(NewsItem.ordered.all).to eql([news_item_z, news_item_x, news_item_y])
end 

上記のテストをモックとスタブに変換する方法を理解するのに途方に暮れています。これは最初の試みですが、明らかにコアとなる概念を誤解しています。

xit "should have an ordered method to retrieve news items in the descending order" do

  news_item_x = mock(NewsItem, created_at: DateTime.new(2012,01,01))
  news_item_y = mock(NewsItem, created_at: DateTime.new(2011,01,01))
  news_item_z = mock(NewsItem, created_at: DateTime.new(2012,03,01))

  NewsItem.should_receive(:ordered).and_return([news_item_z, news_item_x, news_item_y])
  # NewsItem.should_receive(:ordered).ordered # not working.

  # this is pointless as it's not checking the order of anything, just the call.
  NewsItem.ordered
end 

この種のテストでもモッキング/スタブは適切ですか?

アドバイスをいただければ幸いです。

評決:

@arieljuod と @zetetic の両方からすばらしい回答を得ました。私の最初の質問に対して、モックとスタブはここで適切ですか? @zetetic が指摘したように、答えは No のようです。

一方、@arieljuod は、コード スニペットを実際にテストするための非常に優れた方法を提供してくれました (必ずしもモックやスタブを使用する必要はありません)。どちらも有効な答えです。

4

2 に答える 2

2

この種のテストでもモッキング/スタブは適切ですか?

いいえ。

モックとスタブを使用するポイントは、記述したコードをその依存関係から分離することです。の場合、scope依存するものはすべて Rails フレームワークに埋もれています。また、そもそもフレームワーク/ライブラリ コードの内部をテストする必要はありません。元の作成者は既にそれを行っています。

于 2013-03-01T03:51:06.207 に答える
1

少なくともその簡単な例では、パラメーターとして「created_at DESC」を使用して、「順序付けられた」スコープがモデルで「order」を呼び出すことのみをテストする必要があります

describe 'ordered' do
  it 'orders by created_at desc' do
    NewsItem.should_receive(:order).once.with('created_at DESC')
    NewsItem.ordered
  end
end

クエリが希望する順序になることを信頼できます

より複雑なスコープには他の仕様が必要になる場合がありますが、スコープが自明でない場合は、複雑なスコープを小さなスコープに分割して適切にテストし、実際のデータベースクエリのみを実行することができます (最初に実際にオブジェクトを作成してクエリを実行したように)。 (何らかの奇妙な手動のSQLクエリを実行する場合は、それが希望どおりに動作するかどうかをテストする必要があります。そうでない場合は、レールを信頼してください)

編集: コメントに記載されているように、そのコードは機能しません。ActiveRelation オブジェクトに目的の順序セットがあることを確認できます。

describe 'ordered' do
  it 'orders by created_at desc' do
    NewsItem.ordered.order_values.should == ['created_at DESC']
  end
end

そうすれば、アクティブな関係がクエリでその順序を使用することがわかります

于 2013-03-01T19:52:46.143 に答える