PHPUnit Mock Nesneler ve Statik Yöntemler

4 Cevap php

Ben (özellikle Doktrini Modeli kullanılarak) aşağıdaki statik yöntemi test hakkında gitmek için en iyi yol arıyorum:

class Model_User extends Doctrine_Record
{
    public static function create($userData)
    {
        $newUser = new self();
        $newUser->fromArray($userData);
        $newUser->save();
    }
}

İdeal olarak, (verilen kullanıcı verileri ile) "fromArray" ve "tasarruf" denirdi sağlamak için sahte bir nesne kullanmak istiyorsunuz, ancak yöntem statik olarak bu mümkün değil.

Herhangi bir öneriniz?

4 Cevap

Sebastian Bergmann, PHPUnit yazarı, yakın zamanda Stubbing and Mocking Static Methods hakkında bir blog yazısı vardı. PHPUnit 3.5 ve PHP 5.3 yanı sıra geç statik bağlama tutarlı kullanımı ile yapabilirsiniz

$class::staticExpects($this->any())
      ->method('helper')
      ->will($this->returnValue('bar'));

Statik test yöntemleri genellikle, özellikle PHP 5.3 öncesi, (as you probably already noticed) sabit bir parça olarak kabul edilir.

Eğer statik bir yöntem kullanmak için kodunu değiştirmek değil misiniz? Siz aslında, burada bir statik yöntem kullanılarak konum neden ben gerçekten görmüyorum; Bu muhtemelen bazı non-statik kod yeniden yazılmış olabilir, olabilir öyle değil ki?


For instance, could something like this not do the trick :

class Model_User extends Doctrine_Record
{
    public function saveFromArray($userData)
    {
        $this->fromArray($userData);
        $this->save();
    }
}

Sen değil test olacak ne olduğundan emin; ama, artık hiçbir statik yöntemi, en azından ...

Yerine dinamik bir sınıf adını kullanmaya üstlenmeden çalışın, yani:

class UserModel extends Doctrine_Record
{
    protected static $_modelclass;

    static function create ( $data )
    {
        $modelclass = ( is_null(self::$_modelclass) ? 
            get_class(self) : self::$_modelclass
        );

        $model = new $modelclass;
        $model->fromArray($data);
        $model->save();

        return $model;
    }
 } // END UserModel

Mock oluştururken Böylece, sizin alay için statik özelliğini ayarlayabilirsiniz. Hatta bir erişimcisine bu üçlü operatörü üstlenmeden düşünebilirsiniz. Tam zarif değil, ama ne PHP statik yöntemleri ve özellikleri vardır. [

Bu konuda yardımcı AspectMock kütüphane şimdi var:

https://github.com/Codeception/AspectMock

$this->assertEquals('users', UserModel::tableName());   
$userModel = test::double('UserModel', ['tableName' => 'my_users']);
$this->assertEquals('my_users', UserModel::tableName());
$userModel->verifyInvoked('tableName');