2009-05-24 21 views
1

私はいくつかのテストケースを書いています。私はMockオブジェクトを使っているテストケースを持っています。 2つのクラスメソッドが別のクラスメソッドから呼び出されているかどうかを確認する必要があります。ここで私がやったものだ:SimpleTest Mocking Problem

まず、私はモックを生成:

Mock::generate('Parser'); 

その後、私のテストの内側に私は呼ば:

$P = new MockParser(); 

$P->expectOnce('loadUrl', array('http://url')); 
$P->expectOnce('parse'); 

$P->fetchAndParse('http://url'); 

を私の実装コードは次のようになります。

public function fetchAndParse($url) { 
    $this->loadUrl($url); 
    $this->parse(); 
} 

そして、loadUrlメソッドとparse()メソッドが存在します。テストで2つの失敗があります。両方とも「[loadUrl]のコール数が[1]ありました[0]」と言っています。私は何が起こっているのか分かりません - メソッドは、その関数から呼び出されている!私の経験は、.NETの世界でフレームワークをあざけるとされているが

おかげで、

ジェイミー

答えて

4

は、私はあなたが何をしようとしていることは間違っていると思います。

クラスのモックを作成するように頼まれた場合は、どんなモックフレームワークも、そのクラスのすべてのメソッドに対して「スタブ」を生成します。これにはfetchAndParseメソッドが含まれます。だから、あなたのモックオブジェクト$ PでfetchAndParseを呼び出すとき、loadUrlとparseのメソッドは呼び出されません。あなたが実際にやっていることは、 "スタブされた" fetchAndParseメソッドを呼び出すことです。

私はPHPで実際に経験していないので、あなたのテストを試してみたいと思いません。うまくいけば、誰かがそれを行うことができます。

+0

これは本当に役立ちます。つまり、かなりコードを変更する必要があることを意味しますが、少なくとも今何が起こっているのかを知ることができます。ありがとう! –

1

あなたは嘲笑動作の仕組みについて誤解しました。依存関係注入を使用してクラス内のヘルパーオブジェクトを設定すると、注入されたオブジェクトをモックできます。その後、元のオブジェクトの動作(インターフェイス)をシミュレートすることができます。より良い方法は、現在のインターフェースを実装するクラスを作成せずに開発できるので、インターフェースをモックすることです。あなたの例により、

:ところで

interface UrlLoaderInterface { 

    public function load($url); 
} 

class YourParser { 

    protected $urlLoader; 
    protected $source; 

    public function setUrlLoader(UrlLoaderInterface $urlLoader) { 
     $this->urlLoader = $urlLoader; 
    } 

    public function fetchAndParse($url) { 
     $this->loadUrl($url); 
     $this->parse(); 
    } 

    public function loadUrl($url) { 
     $this->source = $this->urlLoader->load($url); 
    } 

    public function parse() { 

    } 

} 

Mock::generate('UrlLoaderInterface', 'MockUrlLoader'); 

class TestYourParser extends UnitTestCase { 

    public function testShouldCallUrlLoaderByFetchAndParse() { 
     $testUrl = 'http://url'; 

     $urlLoader = new MockUrlLoader(); 
     $urlLoader->expectOnce('load', array($testUrl)); 
     $urlLoader->returns('load', 'source', array($testUrl)); 

     $parser = new YourParser(); 
     $parser->setUrlLoader($urlLoader); 
     $parser->fetchAndParse($testUrl); 
    } 

} 

。メソッド名には '、'、 '、' if 'などのような単語を含めることができないので、あなたの例は失敗します。メソッドは1つのことしか実行できません。これらの単語を使用すると、設計されたコードが間違っている可能性があります。