2013-06-25 21 views
5

私はSilexで作業を始めました。私のクラスを適切にユニットテストしようとすると問題が発生します。具体的には閉鎖:( 私はあなたのいずれかがそれを解決する方法を知っているかどうかを確認するために私の問題を説明し、次の行で。 してください、構文が、テスト問題自体に焦点を当てていない。PHPUnitを使用したSilex(モッククロージャ)のテスト

は、私のようなプロバイダを持っていますこの:

<?php 

namespace Foo\Provider; 

use Silex\Application; 
use Silex\ServiceProviderInterface; 

use Foo\Bar; 

class BarProvider implements ServiceProviderInterface { 

    public function register(Application $app) { 
     $app[ 'foo_bar' ] = $app->protect(function() use ($app) { 
      return new Bar($app); 
     }); 
    } 

    public function boot(Application $app) {} 
} 

それから私はfoo_barは要素のインスタンスを取得する必要があります。

<?php 

namespace Foo; 

use Silex\Application; 

class Clazz { 
    protected $bar; 

    public function __construct(Application $app) { 
     $this->bar = $app[ 'foo_bar' ](); 
    } 
} 

これはうまく動作します事は、私が開発していますということです。 TDD(およびPHPUnit)を使用して、私がClazzクラスを適切にテストすることは不可能です。ここ

<?php 

namespace Foo\Test; 

use PHPUnit_Framework_TestCase; 

use Silex\Application; 

use Foo\Bar; 
use Foo\Clazz; 

class ClazzTest extends PHPUnit_Framework_TestCase { 

    public function testConstruct() { 
     $mock_bar = $this->getMock('Foo\Bar'); 

     $mock_app = $this->getMock('Silex\Application'); 
     $mock_app 
      ->expects($this->once()) 
      ->method('offsetGet') 
      ->with('foo_bar') 
      ->will($this->returnValue($mock_bar)); 

     new Class($mock_app); 
    } 
} 

問題はClazzクラスで$アプリ[ 'foo_barは']の後に "()" 内に存在します。 テストを実行しようとすると、「PHPの致命的なエラーが発生します:関数名は文字列でなければなりません...」というエラーが発生します。 私はクラスをこのように単体テストできないことを理解していますが、それを行う適切な方法はわかりません。

最後に複雑な文が$ this-> bar = $ app 'foo_bar';であるため、この文をテストするにはどうすればよいですか?

+0

おそらくgithubはあなたにインスピレーションを与えるでしょう:https://github.com/fabpot/Silex/tree/master/tests/Silex/Tests – qrazi

+0

私はすでにそれを試みましたが、良い例が見つかりませんでした:( – ThisIsErico

答えて

3

私はこの閉鎖を適切にテストすることができたと思います!最終テストは次のようになります。

<?php 

namespace Foo\Test; 

use PHPUnit_Framework_TestCase; 

use Silex\Application; 

use Foo\Bar; 
use Foo\Clazz; 

class ClazzTest extends PHPUnit_Framework_TestCase { 

    public function testConstruct() { 
     $mock_bar = $this->getMock('Foo\Bar'); 

     $mock_app = $this->getMock('Silex\Application'); 
     $mock_app 
      ->expects($this->once()) 
      ->method('offsetGet') 
      ->with('foo_bar') 
      ->will($this->returnValue(function() use($mock_bar) { return $mock_bar; })); 

     new Class($mock_app); 
    } 
} 

モックを返す代わりに、モックを返すクロージャを返します。このようにして、実際のモックで作業している間にエラーは発生しません。

これが正しいアプローチであるかどうか誰にでも教えてください。

関連する問題