Nasıl birden fazla test genelinde PHPUnit bir web hizmeti test alay etmek?

6 Cevap php

Ben phpunit kullanarak bir web servis arayüzü sınıfını test çalışılıyor. Temel olarak, bu sınıf bir SoapClient nesneye çağrıları yapar. Burada anlatılan getMockFromWsdl yöntemini kullanarak PHPUnit bu sınıf test etmek çalışıyorum:

http://www.phpunit.de/manual/current/en/test-doubles.html#test-doubles.stubbing-and-mocking-web-services

Ben bu aynı sınıftan, her zaman ben kurulum nesne birden fazla yöntemleri test etmek istiyorsanız Ancak, ben de kurulum zorunda sahte WSDL SoapClient nesne. Bu atılmış olması, ölümcül bir hataya neden oluyor:

Fatal error: Cannot redeclare class xxxx in C:\web\php5\PEAR\PHPUnit\Framework\TestCase.php(1227) : eval()'d code on line 15

Nasıl WSDL kapalı her seferinde yeniden oluşturmak zorunda kalmadan birden testler arasında aynı davalarını nesnesini kullanabilirsiniz? Bu sorun gibi görünüyor.

-

Burada TestCase içinde kurulum yöntem, bakmak için bazı kod göndermek istedi edilmiş olması:

protected function setUp() {
    parent::setUp();

    $this->client = new Client();

    $this->SoapClient = $this->getMockFromWsdl(
        'service.wsdl'
    );

    $this->client->setClient($this->SoapClient);
}

6 Cevap

Bu ideal bir çözüm değildir, ancak kurulumunda örneğin, SOAP alay bir "rastgele" sınıf adı verin

$this->_soapClient = $this->getMockFromWsdl( 'some.wsdl', 'SoapClient' . md5( time().rand() ) );

Bu, en azından kurulum denir zaman o hatayı alamadım sağlar.

Temel kullanım için, böyle bir şey çalışmak. PHPUnit perde arkasında bazı büyü yapıyor. Eğer sahte nesne önbelleğe, bu redeclared olmayacaktır. Sadece bu önbelleğe örneğinden yeni bir kopyasını oluşturmak ve gitmek için iyi olmalıdır.

<?php
protected function setUp() {
    parent::setUp();

    static $soapStub = null; // cache the mock object here (or anywhere else)
    if ($soapStub === null)
        $soapStub = $this->getMockFromWsdl('service.wsdl');

    $this->client = new Client;
    $this->client->setClient(clone $soapStub); // clone creates a new copy
}
?>

Alternatif olarak, muhtemelen get_class ile sınıfının adını önbelleğe ve sonra yeni bir örneğini oluşturmak, yerine bir kopya daha yapabilirsiniz. Ben PHPUnit başlatma için yapıyor ne kadar "sihirli" Emin değilim, ama denemeye değer.

<?php
protected function setUp() {
    parent::setUp();

    static $soapStubClass = null; // cache the mock object class' name
    if ($soapStubClass === null)
        $soapStubClass = get_class($this->getMockFromWsdl('service.wsdl'));

    $this->client = new Client;
    $this->client->setClient(new $soapStubClass);
}
?>

Nokta tüm test dosyanın yürütülmesinden başına bir kez sahte bir sınıf tanımı elde etmek ise neden) (setUp olarak mock yaratıyor? Eğer doğru hatırlıyorum o "bu" test sınıfında tanımlanan her testten önce çalıştırılır ... setUpBeforeClass deneyin ()

Dan http://www.phpunit.de/manual/3.4/en/fixtures.html

In addition, the setUpBeforeClass() and tearDownAfterClass() template methods are called before the first test of the test case class is run and after the last test of the test case class is run, respectively.

Burada benim 0,02 $ Ekleniyor .. Geçenlerde bu aynı durum karşısında ve burada bazı hayal kırıklığı ben bunu çözmek başardı nasıl sonra koştu:

class MyTest extends PHPUnit_Framework_TestCase
    protected static $_soapMock = null;

    public function testDoWork_WillSucceed( )
    {
        $this->_worker->setClient( self::getSoapClient( $this ) );
        $result = $this->_worker->doWork( );
        $this->assertEquals( true, $result['success'] );
    }

    protected static function getSoapClient( $obj )
    {
        if( !self::$_soapMock ) {
            self::$_soapMock = $obj->getMockFromWsdl( 
                'Test/wsdl.xml', 'SoapClient_MyWorker'
            );
        }

        return self::$_soapMock;
    }
}

Ben kendi test sınıfında birçok 'işçi', her var olan ve her biri bir alay soap nesneye erişimi gerekiyor. Için ikinci parametre getMockFromWsdl Eminim her benzersiz bir adı geçiyordu yapmak zorunda (örneğin SoapClient_MyWorker) ya da aşağı çökmesini phpunit getirecek.

Ben olsun veya statik bir işlevi SOAP alay alma ve bir parametre olarak $this ileterek getMockFromWsdl fonksiyonuna erişim almıyorum bunu gerçekleştirmek için en iyi yol olduğundan emin değilim, ama Orada ya gitmek.

PHPUnits sınamak için testi bir nesne geçmek için tek yol testi bağımlılığı ile, belirli bir nesne başlatmasını çok yıpratıcı eğer / zaman alıcı:

<?php
/**
* Pass an object from test to test
*/
class WebSericeTest extends PHPUnit_Framework_TestCase
{

    protected function setUp() {
        parent::setUp();
        // I don't know enough about your test cases, and do not know
        // the implications of moving code out of your setup.
    }

    /**
    * First Test which creates the SoapClient mock object.
    */
    public function test1()
    {
        $this->client = new Client();

        $soapClient = $this->getMockFromWsdl(
            'service.wsdl'
        );

        $this->client->setClient($this->SoapClient);
        $this->markTestIncomplete();
        // To complete this test you could assert that the
        // soap client is set in the client object. Or
        // perform some other test of your choosing.

        return $soapClient;
    }

    /**
    * Second Test depends on web service mock object from the first test.
    * @depends test1
    */
    public function test1( $soapClient )
    {
        // you should now have the soap client returned from the first test.
        return $soapClient;
    }

    /**
    * Third Test depends on web service mock object from the first test.
    * @depends test1
    */
    public function test3( $soapClient )
    {
        // you should now have the soap client returned from the first test.
        return $soapClient;
    }
}
?>

PHPUnit WSDL dayalı alay için bir sınıf oluşturur. Classname, sağlanan değilse,. Wsdl dosya inşa edilmiştir, bu yüzden her zaman aynı. Yine sınıf oluşturmak çalıştığında testler karşısında, o çöker.

İhtiyacınız olan tek şey, Mock tanımı kendi bir classname eklemek, böylece PHPUnit otomatik adı yaratmaz, $ this-> getMockFromWsdl ikinci argüman fark olduğunu:

protected function setUp() {
   parent::setUp();

   $this->client = new Client();

   $this->SoapClient = $this->getMockFromWsdl(
      'service.wsdl', 'MyMockClass'
   );

   $this->client->setClient($this->SoapClient);
}

İstediğiniz gibi şimdi birçok müşterimiz oluşturabilirsiniz, ancak her biri için classname değiştirin.