Can I "Mock"

6 Cevap php

'Sahte' doğru sözcüğü ise ... bilmeden.

Her neyse, ben zaman tabanlı olduğu için bazı testleri yazmak için çalışıyorum kalıtsal bir kod tabanı var. too belirsiz olmamaya çalışıyorum, kod bir öğenin tarihine bakarak ve o madde artık bir zaman eşik tabanlı olup olmadığını belirleme ile ilgilidir.

Bir noktada ben de bu tarihin bir şey ekleme ve eşik artık (doğru, besbelli, ve) değişmiş olduğunu kontrol test etmek gerekir.

Vuruyorum sorun ben test (zaman çağrıları kullanarak) ve bu yüzden ben 'olduğu gerçeğine dayanarak, eşik zaman olmalıdır tam olarak bilmek gerçekten zor bulma yaşıyorum ben o kod parçası o zaman () fonksiyonu çağrılır olacak tam olarak ne zaman oldukça emin değilim.

Benim soru temelde şudur: 'override' benim için bazı yolu zaman vardır () aramak, ya da bir şekilde benim testleri bir 'bilinen süre' olarak çalışan bu tür, zamanı 'dışarı taklit'?

Ya Ben sadece ihtiyaç halinde nedense bana belli bir zamanı kullanmaya zorlamak için izin vermek, ben test olduğum kodda bir şey yapmak zorunda gidiyorum gerçeğini kabul etmek gerekiyor?

Her iki şekilde de, testi dostu zamana duyarlı işlevselliği geliştirmek için herhangi bir 'ortak uygulamalar' vardır?

Edit: Part of my problem, too, is the fact that the time that things occurred in history affect the threshold. Here's an example of part of my problem...

Eğer bir muz var ve yemiş gerektiğinde dışarı çalışmaya çalışıyoruz düşünün. Kullanıcının biz bitiminden 4 gün eklemek, from the time the spray was applied bu durumda, bazı kimyasal ile püskürtülür sürece, 3 gün içinde dolacak diyelim. Sonra, bunu dondurma ile kendisine başka 3 ay ekleyebilirsiniz, ancak dondurulmuş eğer o zaman biz sadece thaws sonra kullanmak için 1 gün var.

Bu kuralların tüm tarihsel zamanlara tarafından belirlenir. Ben bir kaç saniye içinde test Dominik'in öneri kullanabilirsiniz katılıyorum, ama benim tarihsel verilerin ne? Ben sadece sinek o 'yaratmak' gerekir?

Eğer siz veya söylemek mümkün olmayabilir, ben hala bu 'test' kavramının tüm bir asmak için çalışıyorum ;)

6 Cevap

Geçenlerde PHP 5.3 ad kullanıyorsanız büyük olduğunu başka bir çözüm geldi. Eğer geçerli isim alanı içinde yeni bir zaman () işlevi uygulamak ve sizin testlerde dönüş değeri paylaşılan bir kaynak oluşturabilirsiniz. Sonra zaman () herhangi bir vasıfsız çağrı yeni bir fonksiyon kullanacağız.

Daha fazla okuma için benim blog ayrıntılı olarak açıklanan

Şahsen, ben test işlevleri / yöntemleri () zaman kullanılarak tutun. Lütfen test kodu olarak, sadece) süre (eşitlik için test değil emin olun, ama sadece az 1 veya 2 saat farkı için (fonksiyon yürütmek için gereken ne kadar zaman bağlı)

Basit çözüm PHP zaman () işlevi geçersiz kılmak ve kendi sürümü ile değiştirmek olacaktır. Ancak, yerleşik yerini alamaz PHP fonksiyonları kolayca (see here).

Kısacası, tek yolu soyut zaman için () test için ihtiyacınız zaman dönecekti kendi bazı sınıf / işlevi diyoruz.

Alternatif olarak, bir sanal makinede test sistemi (işletim sistemi) çalıştırın ve tüm sanal bilgisayarın saatini değiştirmek olabilir.

Sen runkit uzantısını kullanarak PHP'nin time () fonksiyonu overide olabilir. Emin On runkit.internal_overide set yapmak

[Runkit] Kullanımı [1] uzantısı:

define('MOCK_DATE', '2014-01-08');
define('MOCK_TIME', '17:30:00');
define('MOCK_DATETIME', MOCK_DATE.' '.MOCK_TIME);

private function mockDate()
{
    runkit_function_rename('date', 'date_real');
    runkit_function_add('date','$format="Y-m-d H:i:s", $timestamp=NULL', '$ts = $timestamp ? $timestamp : strtotime(MOCK_DATETIME); return date_real($format, $ts);');
}


private function unmockDate()
{
    runkit_function_remove('date');
    runkit_function_rename('date_real', 'date');
}

Hatta bu gibi mock test edebilirsiniz:

public function testMockDate()
{
    $this->mockDate();
    $this->assertEquals(MOCK_DATE, date('Y-m-d'));
    $this->assertEquals(MOCK_TIME, date('H:i:s'));
    $this->assertEquals(MOCK_DATETIME, date());
    $this->unmockDate();
}

İşte fab yazılan bir yanı var. Ben bir eval kullanarak ad merkezli kılma yaptım. Bu şekilde, sadece test ve benim kod kalanı için çalıştırabilirsiniz. Ben benzer bir işlevi çalıştırabilirsiniz:

function timeOverrides($namespaces = array()) {
  $returnTime = time();
  foreach ($namespaces as $namespace) {
    eval("namespace $namespace; function time() { return $returnTime; }");
  }
}

benim testler sadece (inç) olarak adlandırılan zaman ad alanlarına ne izlemek zorunda böylece daha sonra deney kurulum timeOverrides(array(...)) geçmek