2009-06-24 8 views
5

フィールドへのアクセスを許可しない複雑なオブジェクトを返すメソッドをテストする方法このスニペットを検討してください。単体ではないオブジェクトを返すメソッドをテストする

public ResultState getResultState(){ 
    ResultState resultState = new ResultState(); 
    // logic // 
    this.resultState = resultState; //set parent class field 
    return resultState; 
} 

ResultStateは、メソッドとフィールドをほとんど使用できないオブジェクトです。 私は以外に、このような方法をテストする方法、他のとして無知午前:

assertNotNull(object.getResultState()) //the return ResultState is used by other class methods 

私の質問は一般的ですが、私はそれは私がテストに行く方法についてのヒントを得るために午前どのように必死に示していることを期待しています。 ..助けてくれてありがとう

答えて

11

結果については何が重要ですか?おそらくそれは何かを行うことができますか、それは役に立たない結果になるでしょう。この場合、作業コードと壊れたコードとはどのような違いがありますか?

(私は問題を明るくしようとしていません - 時には、カプセル化を厳密にしても効果的にテストするのは非常に難しいですが、テストを簡単にするためにオブジェクトを少し開ける価値があります...)

+0

+1 - 私が言うつもりだった言葉 –

+0

Jon、 良い質問 - 何が重要なのか。 これについて考えると、結果の最も重要なことは、それを使用するメソッドによって期待されるオブジェクトでなければならないということです。そしてこれは// LOGICのコードの// LOGICセクションで行われます。ここでLOGICは "this"のフィールドを操作します 私は以下のテストシナリオを実行しました: 1.このフィールドのセッターとゲッターを設定しました 2. set + ve(良い値)と-ve(悪い値) 3.それらを例外なく構築してください... これは簡単なテストですが、最初は良いです。ありがとう –

5

このオブジェクトは何をしますか?フィールドなどを照会できない場合は、そのオブジェクトに渡すオブジェクトに作用すると思いますか?その場合、同じインタフェースを実装するダミーオブジェクトを渡すことができますが、結果オブジェクトが適切な引数で期待通りの順序でそれを呼び出すかどうかチェックします。

ActedUponゲッター慣例により、全ての

2

まず(ここでJMockようなモックフレームワークを使用することが理想的である)インタフェースであり、「通常」の実装、および検証の実装を有するであろう

public class ResultObject { 
    public void actOn(ActedUpon obj) { 
     // does stuff 

副作用があってはならない。だから、それはほとんど確かに悪い考えです。

this.resultState = resultState;

をゲッターに入れます。

返されたresultStateはの一部である必要があります。の目的である必要があります。 resultStateが必要な処理を実行するかどうかをテストします。

0

何をテストすることは、あなたがo.setResultState(resultState)を呼び出した後、あなたはo.getResultStateとresultStateを(得ることができるということだけである場合)、テストのような非常に単純なものになるだろう:

ResultState resultState = new ResultState(...); 
o.setResultState(resultState); 
assertEquals(resultState, o.getResultState()); 
2

そのコードに基づいています。 Not Nullのチェックで十分だと思います。返されるResultStateの機能性をチェックすることは、ResultStateのテストに属します。 getResultState()の機能をテストしようとしています。それが行う唯一のことは、新しいオブジェクトを作成し、this.resultStateにそのオブジェクトへの参照を保存することです。だからそれが作成されているかどうか確認し、参照を保存したかどうか確認してください。

2

ResultStateオブジェクトを作成するのに、getResultState()を使用していることは残念ですが、それは本当にあなたのブロッカーです。

protected ResultState initResultState () 
{ 
    this.resultState = new ResultState(); 
    // Initialization Logic... 
    return this.resultState; 
} // END initResultState 

public ResultState getResultState () 
{ 
    if (this.resultState === null) 
    { 
     return this.initResultState(); 
    } 

    return this.resultState; 
} // END getResultState() 

この位置から、ゲッターメソッドをテストする方が簡単です。それでももちろん、保護initResultState()であなたを残し

/** 
* The test fixutre's initResultState() method merely returns a simple Stub of 
* the ResultState object, which can be more easily interrogated. 
*/ 
public ResultState initResultState () 
{ 
    return new Stub_ResultState(); 
} // END initResultState 

:尋問することができinitResultState()のために知られてResultStateスタブを返し子孫クラス、すなわちを定義します。以下のリファクタリングを考えてみましょう:

protected ResultState initResultState (ResultState newResultState) 
{ 
    this.resultState = newResultState; 
    // Initialization Logic... 
    return this.resultState; 
} // END initResultState 

public ResultState getResultState () 
{ 
    if (this.resultState === null) 
    { 
     return this.initResultState(new ResultState()); 
    } 

    return this.resultState; 
} // END getResultState 

これは、あなたが例えば、操作し、その後尋問するために別のResultStateスタブオブジェクトを渡すことができるような子孫クラスでgetResultState()メソッドをオーバーライドすることを許可:

/** 
* The test fixture's getResultState() method always acts as a passthrough for 
* initResultState(), which is protected, so that the output of the protected 
* method can be interrogated. 
*/ 
public ResultState getResultState () 
{ 
    return this.initResultState(new Stub_ResultState()); 
} // END getResultState 

この位置から、2つのテストフィクスチャが必要です。ゲッタの機能をテストするためにinitResultState()の動作をオーバーライドします。 initResultState()の動作をテストするためのgetResultState()の動作を無効にする別のものです。両方ともResultStateクラスの子孫であるが、単体テストでの問い合わせのための親オブジェクトの内部値へのパブリックアクセスを提供するStub_ResultStateクラスのインスタンスを使用します。

私はそれが理にかなっていることを希望しますが、説明を求めることは自由です。

0

getterでnewを実行すると、ResultStateの具体的な実装をコミットしています。現在のケースでは、その状態について不透明な実装を意味します。

ResultStateを新しく作成する代わりに、それを工場から取得し、モックResultStateを置き換える何らかの方法を提供しているとしたら、getResultState()が行っていることを確認できますResultStateオブジェクトを作成してから返すまでの間、

この効果を得る簡単な方法は、オーバーライド可能なメソッドでResultStateの作成を分解することです。例えば、

public ResultState getResultState() { 
    ResultState resultState = createResultState(); 
    ... 

protected ResultState createResultState() { 
    return new ResultState(); 
} 

はその後、あなたのテストクラスが同じパッケージ内にあると仮定すると、あなたはモックを返すように)getResultStateを(上書きされますのインラインサブクラスを作成することができます。

これは機能しますが、テストを書くのは壊れやすい方法です。

別のアプローチは、これを使用すると、依存性注入フレームワークは最適です何かであるオブジェクトへResultStateFactoryを注入する適切な方法を把握する必要があり

public ResultState getResultState() { 
    ResultState resultState = _resultStateFactory.newResultState(); 
    ... 

のようなものに向かうことです。テストのために、適切な期待をつけて準備されているモックResultStateを返すファクトリを挿入します。これにより、テスト結果が「ResultStateオブジェクトを返す前に正しく処理するgetResultState()」に減少します。