2011-12-11 1 views
3

私はSW Devとして募集されています。私はRSPECとRRを使ってユニットテストをルビーにしようとしていますが、特定の戦略を決定するのは大変でした。すでに書かれたコードに単体テストを書き込むために割り当てられています。Rubyユニットテストテクニック、モックとスタブ

は、法1と呼ばれる大きな方法の一部である次のコードを考えてみましょう:

if (["5234541252", "6236253223"].include?(self.id)) 
    self.DoCheck 
    logs.add 'Doing check', "id = #{self.id}" 
    return 
    end 

方法のこの部分に関連するユニットテストのようなものとなってきたでしょう:

"should do check only if id = 5234541252 or 6236253223"

しかし、私は基本的にベストプラクティスを含むいくつかの質問に就いています:

DoCheck RRとRSPECを使って "method1"から呼び出されましたか?

私はdont_allow(Object).DoCheckを使ってみましたが、動作しません。

describe :do_route do 
    it "should do check only if id = 5234541252 or 6236253223" do 
    user = Factory(:User) 
    user.id = "5234541252" 

    dont_allow(user).DoCheck 
    user.method1 
end 

「DoCheck」が呼び出されたかどうかを判断する他の方法はありますか?

+1

これが「大きな方法の一部」であるという事実は、巨大な赤旗です。より良い、より簡単で、より効果的なテストのために、コードをリファクタリングする必要があります。また、InitialCapsでメソッド名を使用することによって証明されているように、他の多くの問題が疑われます。 –

+0

私は全く同意しますが、残念ながら、コードをリファクタリングすることは現在のところ問題です。 –

+0

WHAT ???彼らはコードを改善するつもりがない場合、ユニットテストのために何を望んでいますか? –

答えて

0

テスト中のオブジェクトに対して「パーシャルモッキング」テクニックを使用できます。これは、user.method1がにメッセージDoCheckを送信するように設定する必要があることを意味します。 RSpecはshould_receive()メソッドでこの期待値を設定できます。予想が満たされない場合、テストは失敗します。

次のコードを試してみてください。

describe :do_route do 
    it "should do check if id = 5234541252 or 6236253223" do 
    user = Factory(:User) 
    user.id = "5234541252" 

    mock(user).DoCheck # set expectation that DoCheck will be called 

    user.method1 # execute 
    end 
end 

更新

しかし理由は、彼らモックオブジェクトと部分モックの使い方に注意してください:この期待は、このように見えるかもしれRR

describe :do_route do 
    it "should do check if id = 5234541252 or 6236253223" do 
    user = Factory(:User) 
    user.id = "5234541252" 

    user.should_receive(:DoCheck) # set expectation that DoCheck will be called 

    user.method1 # execute 
    end 
end 

をテストコードをテスト中のコードの現在の動作に密接に関連させます。将来このコードをリファクタリングするつもりならば、失敗したテスト(モックを使うテスト)がたくさん出る可能性があります。モック(インプットアウトプット)を使わずにテストコードを試し、テスト中のクラスの意図を明確に説明している場合にのみモックを使用してください。モックでテストを書くときは、常にこのメソッドが別のメソッドを呼び出すか、本当に気にかけているのがメソッドの出力か他のものかを主張する必要があります。

希望すると便利です。

+0

チップのおかげで、私はいつも心に留めていますが、残念ながら私は –

+0

@MikeySで十分である別の非モックテストを思い付くことができませんでした。次に、モックでテストを書く:)あなたが今必要とするのは、テストでもっと練習をすることだけです。いくつかの経験をすると、既存のクラスをテストする優れた方法が見えます。 また、既存のコードのテストを書く上で優れた本があります:[マイケルフェザーズのレガシーコードで効果的に働く](http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052) 。 –

+0

情報をもう一度ありがとう...私が気づいた別のことは、私はuser.saveを使用しなければならないということです! if文が "t​​rue"(ユーザーが明らかにActiveRecord :: Baseを継承している)と評価するために、私が作成したユーザーインスタンスがメモリに置かれているだけでは不十分です。 –

関連する問題