php

2010-11-19 24 views
16

birim sınama tarihi işlevleri için geçerli zamanı nasıl değiştiririm birim-test tarih-manipülasyon sınıfı için php olarak geçerli saati (yani zaman() çıktısını nasıl değiştiririm? Eğerphp

+0

http://stackoverflow.com/questions/530649/is-it-possible-to-replace-monkeypatch-php-functions –

+0

Bazı kodları gösterebilir misiniz? Benim düşünceme göre, eğer birim testi için time() 'i geçersiz kılmanız gerekiyorsa, * test ya da kod ile ilgili bir sorun olabilir. – netcoder

+0

sınıf geçerli tarihi değiştirir. Tüm yöntemlerin sözcükleri her tarihte doğru bir şekilde kontrol etmek istiyorum. – happytoad

cevap

3

geliyor. Sizi sınıfın içinde kullandığınız time() işlevini kullanırken, birim sınaması yaparken, sizin için zamanı sağlayan yöntemler/sınıfların çıktısını kontrol ettiğinizden emin olmak istersiniz. Size zaman kazandıran ve birim testlerinize atabilen bir Zaman sınıfı oluşturduğumu söyleyebilirim.

+0

Yani, sınama mantığını yalnızca sınama için değiştirmeliyim? – happytoad

+1

@happytoad - hayır sadece, tarih kontrol sınıfınızda aradığınız zamanı kontrol etmek için 'time()' aramanız gerekiyor. Örneğin, parametre olarak test ettiğiniz işleve bir zaman değeri iletebilir veya tarih sınıfınızın yapıcısına iletebilirsiniz. – rojoca

+1

, bu yüzden zamanı değiştirmenin bir yolu yok. Şu anki zamanı değiştirmek gibi basit bir şeyin test için uygun olmaması garip. serseri. Teşekkürler. – happytoad

3

Benim tahminim sizin bağımlılıkları ile mücadele eden bir tarih manipülasyon sınıfından time() bağımlılığını kaldırmak gerekiyor gibi

5

Son zamanlarda PHP 5.3 ad alanlarını kullanıyorsanız harika bir çözüm buldum. Mevcut ad alanınızda yeni bir time() işlevi uygulayabilir ve testlerinizde dönüş değerini ayarladığınız paylaşılan bir kaynak oluşturabilirsiniz. Sonra, herhangi bir niteliksiz çağrıya time() yeni fonksiyonunuzu kullanır. Daha fazlasını okumak için

ben ayrıntılı olarak nitelendirdi benim blog

Sen bir arayüz tabanlı kalıtım modeli düşünebilirsiniz
+1

Geçtiğimiz günlerde, "time()" gibi deterministik olmayan PHP işlevlerinin alay edilmesi için bu dili kullanan kütüphaneyi [php-mock] (https://github.com/malkusch/php-mock) uygulamıştım. –

3

: Bir alacaktı şimdiki zaman ile çalışmak gerekir

interface iClock 
{ 
    public function getTime(); 

} 

class SystemClock implements iClock 
{ 
    public function getTime() 
    { 
     return time(); 
    } 
} 

class FakeClock implements iClock 
{ 
    private $time; 

    function __construct($time) 
    { 
     $this->time = $time; 
    } 

    public function getTime() 
    { 
     return $this->time; 
    } 

    // you could have more functions to advance the time, etc. 
} 

Kendi sınıfları iClock arabirim türünün yapıcı parametresi.

class YourOwnClass 
{ 
    private $clock; 

    function __construct(iClock $clock) 
    { 
     $this->clock = $clock; 
    } 

    function someFunction() 
    { 
     $now = $this->clock->getTime(); 

     // whatever 
     return $now; 
    } 
} 

Sonra basitçe saat tipini enjekte ederdi Eğer bir birim, testteki olsun veya olmasın bağlı olarak gördük:

$realWorldInstance = new YourOwnClass(new SystemClock()); 
echo $realWorldInstance->someFunction(); 
$unitTestInstance = new YourOwnClass(new FakeClock(1234)); 
echo $unitTestInstance->someFunction(); 

BTW - Sık sık bu modeli kullanan .NET'de de. Ayrıca, Noda Time tarafından sağlanan IClock arayüzüne yerleştirilmiştir. Bu şablonun PHP'de çalışmamasının bir nedenini göremiyorum. Tam sayı zaman damgası yerine bir DateTime döndürmeyi seçebilirsiniz, ancak yukarıdaki kalıbı kullanmak için gereken minimum değerdir.