2013-07-01 13 views
5

私は注文書を処理し、支払いを設定してからモデルの関連付けを設定する、サービスと呼ばれるサービスオブジェクトを作成しました。Rspecによるサービスのテストとモック

このクラスは、initializepayという2つのメソッドを持つトランザクションと呼ばれます。 spec/services/(それはapp/servicesにあります)でテストしています。

initializeメソッドは、accountを受け取り、注文を処理するためにユーザーが渡します。

payをrspecでテストしようとしています。どのように実際にそのようなテストを行うのですか?この機能には多くのことがあります。たとえば、新しいモデルを作成し、それらの間にいくつかの関連付けを設定します。

次のようにこれまでのところ、私は二重のaccountを作成しました:

@account = double("account", :confirmed => true, :confirmed? => true)

をしかし、多くの機能(および団体)があるトランザクション賃金法に用いられます。 (私はテストでTransaction.payを呼び出した後)ので、これらの団体が呼ばれ、たとえば、それはエラーを返します:

ActiveRecord::AssociationTypeMismatch: 
Business(#70250016824700) expected, got RSpec::Mocks:. 

businessモデルはちょうどaccountのような二重で、@accountに属性として追加しました。 Transaction.payがそこに新しいモデルと関連を作成するとき、どうすれば私のTransaction.payをテストできますか?

上記のようにすべてをモックする必要がありますか?それとももっと良い方法がありますか?

私はFactoryGirlを使用していますが、accountモデルではDeviseを使用しているため、使用できません。 Deviseテストヘルパーはコントローラの外では使用できません。サービスでテストしているので動作しません。

+0

FactoryGirlとDeviseは問題ではありません。サービステストはモデルテストと同様でなければなりません。モデルにFactoryGirlを使用できるはずですね。 – phoet

答えて

7

それはあなたがあなたのトランザクションクラスのコードを提供していませんでしたから、具体的には難しいのですが、高いレベルで、ここで私がお勧めしたいものです。

  • がfactorygirlや工夫ヘルパーを使用しないでください - 理想的には、このクラスの単体テストを書いているので、外部依存関係は必要ありません。
  • あなたが扱っているモデルインスタンスを除外します。これは、accountで行っています。
  • サービス内で使用されている外部クラス(たとえばBusiness)を除外します。クラスのインスタンスを作成する場合は、それらも倍増します。ここで

はありません実際の実装と漠然とした例です:

require './app/services/transaction' 

describe Transaction do 
    let(:transaction) { Transaction.new account, :foo => 'bar' } 
    let(:account)  { double 'Account', :confirmed? => true } 
    let(:business) { double 'Business', :save => true } 

    before :each do 
    stub_const 'Business', double(:new => business) 
    end 

    describe '#pay' do 
    it "does stuff" do 
     # ... 

     transaction.pay 

     # ... 
    end 
    end 
end 

あなたは、私が唯一のトランザクションファイルを必要としました注意しましょう - これは、あなたはそれが何に依存するか、他のクラスを認識するのに役立ちますあなたのために定数をスタブしたり、必要に応じて他のファイルを必要とします(理想的には)。この仕様の実行時間はずっと良くなります。

また、アカウントダブルでconfirmedではなく、confirmed?とスタブしました。 Railsの観点からは同じことを意味しますが、どちらか一方を一貫して使用する方が良いでしょう。

セットアップ(たくさんの定数とテストの倍数)がある場合は、このトランザクションクラスを複数のより具体的なクラスに分割する必要があることを示す記号として使用します。

関連する問題