Daha fazla test edilebilir bir şey (PHP) içine aynı nesnenin bağımlılıkları olan bir yöntem üstlenmeden

5 Cevap php

Şu anda diğer nesnelerden aynı nesne ve diğerleri diğer yöntemleri, bazı aramak zorunda benim sınıf içinde bir yöntemi var.


class MyClass
{
    public function myMethod()
    {
        $var1 = $this->otherMethod1();
        $var2 = $this->otherMethod2();
        $var3 = $this->otherMethod3();
        $otherObject = new OtherClass();
        $var4 = $otherObject->someMethod();

        # some processing goes on with these 4 variables
        # then the method returns something else

        return $var5;
    }
}

Ben bütün TDD oyuna yeni değilim, ama think I tuşuna binaların anlamış olmanın biraz daha test edilebilir kod Kontrol Bağımlılık Enjeksiyon / İnversiyon için bazı strateji ile kompozisyon, gevşek bir bağlantı vardır için.

Nasıl bu özel durumun daha test edilebilir bir şey bir yöntem üstlenmeden hakkında nasıl gidiyor?

Ben kolaylıkla alay / işbirlikçi yöntemleri saplama böylece ben, bir parametre olarak metoda $this nesne başvurusu geçmek? Bu tavsiye edilir veya denize gidiyor?


class MyClass
{
    public function myMethod($self, $other)
    {
        # $self == $this
        $var1 = $self->otherMethod1();
        $var2 = $self->otherMethod2();
        $var3 = $self->otherMethod3();
        $var4 = $other->someMethod();

        # ...

        return $var5;
    }
}

Ayrıca, tek testler için söz konusu yöntemin bir saplama / mock nasıl enjekte düşünmek için olduğu gibi bağımlılıkları, TDD ile oldukça büyük bir anlaşma olduğunu bana açıktır. En TDDers kamu bağımlılıkları için birincil strateji olarak DI / IOC kullanıyor musunuz? hangi noktada abartılı hale gelir? Eğer verimli yapmak için bazı öneriler verebilir?

5 Cevap

Bunlar bazı iyi sorular ... bana ilk ben gerçekten hiç JS bilmiyorum, ama ben bir birim test duyuyorum ve bu konular ile ele diyelim. Önce bunu kullanarak değilse JSUnit varolduğunu işaret etmek istiyorum.

Ben senin yöntem aynı sınıf içindeki diğer yöntemler arayarak hakkında çok fazla endişe olmaz ... bu ne bağlıdır. Ne daha beni endişelendiriyor ne kadar karmaşık bağlı olarak, diğer nesnenin yaratılmasıdır.

Eğer ağ üzerinden işlemleri her türlü yapan bir sınıf başlatmasını Örneğin, basit bir birim testi için çok ağır. Şebeke arızaları, saat: nesne ağda, ağda gidiş yükü ödemeden faaliyetlerinden almayı beklediğiniz sonucu olabilir böylece Ne yapmayı tercih edeceğini sınıf bağımlılık dışarı sahte olduğunu , vs ..

Başka bir nesnenin geçen biraz dağınık. Ne insanlar genellikle yapmak diğer nesne örneğini oluşturmak için bir fabrika yöntemini olması. Fabrika yöntemi (genellikle bir bayrağı üzerinden) gerçek nesne veya mock örneğini olup olmadığını test olsun veya olmasın dayalı, karar verebilir. Aslında, diğer nesne size sınıfının bir üyesi yapmak isteyebilirsiniz, ve kurucu içinde, fabrika aramak, ya da orada mock veya gerçek bir şey örneğini isteyip istemediğinizi karar. Bu doğru değeri dönecektir, böylece kurulum fonksiyonu içinde ya da test durumlarda içinde size alay nesne üzerinde özel koşullarını ayarlayabilirsiniz.

Ayrıca, sadece aynı sınıfta diğer işlevler için testler var emin olun ... Bu yardımcı olur umarım!

Bu sınıfın bütün fikri oldukça doğru değil gibi görünüyor. TDD senin sınıfları değil, yöntemler deniyoruz. Bir yöntem sorumluluğu kendi vardır ve kendi bulunuyor sağlıyorsa (ayrı test edilebilir) işlevselliği ayrı bir sınıfa taşınmalıdır. Aksi takdirde sadece bütün OOP kapsülleme şeyi keser. Özellikle de tek sorumluluk ilkesi kırar.

Senin durumunda, başka bir sınıfa test yöntemi ayıklamak istiyorum ve bağımlılıklar gibi $var1, $var2, $var3 ve $other enjekte. $other, hem de alay edilmelidir sınıf test herhangi bir nesne bağlıdır.

class TestMyClass extends MyTestFrameworkUnitTestBase{
     function testMyClass()
     {
          $myClass = new MyClass();
          $myClass->setVar1('asdf');
          $myClass->setVar2(23);
          $myClass->setVar3(78);
          $otherMock = getMockForClassOther();
          $myClass->setOther($otherMock);
          $this->assertEquals('result', $myClass->myMethod());
     }
}

Ben kullanmak Temel kural şudur: Ben bir şey denemek istiyorsanız, bunu bir sınıf yapmak gerekir. Bu olsa PHP her zaman doğru değildir. Ama bu vakaların% 90 PHP çalışır. (Benim tecrübeme dayanarak)

Ben yanlış olabilir, ama ben / sınıfları müşterilerine siyah kutular olmalıdır nesneleri izlenimi altında değilim, ve böylece onların test müşterilerine (ben arıyorum terim olduğunu düşünüyorum kapsülleme).

Yapabileceğiniz birkaç şey var:

Yapılacak en iyi şey sahte olduğunu, burada böyle bir kütüphane bulunuyor: http://code.google.com/p/php-mock-function

Bu, yalnızca istediğiniz belirli işlevleri taklit izin vermelisiniz.

Bu işe yaramazsa, bir sonraki en iyi şey MyClass sınıf içinde bir nesne yöntemi olarak method2 uygulanmasını sağlamaktır. Ben daha kolay yöntemleri bu bulmak doğrudan alay yöntemleri değil eğer:

class MyClass {
  function __construct($method2Impl) {
    $this->method2Impl = $method2Impl;
  }
  function method2() {
    return $this->method2Imple->call();
  }
}

Başka bir seçenek yöntem, farklı davranır, böylece bir "test edilen" bayrak eklemektir. Ben de bu tavsiye etmiyoruz - eninde sonunda kod yolları farklı ve kendi hata etmiş olacak.

Başka bir seçenek ihtiyaç davranışları alt sınıf ve geçersiz olacaktır. Eğer :) hataları kendisi gerekir ki noktasına geçersiz mock özelleştirme bitireceğiz beri-gerçekten-do bu öneririz değil.

Eğer bir yöntemi taklit gerekiyorsa onun çok karmaşık, çünkü nihayet, o can kendi nesnesi içine taşımak ve (esasen i method2Impl tekniği kullanılarak kompozisyon kullanmak için iyi bir işaret olabilir ) yukarıda.

Muhtemelen, bu TDD sorunları besliyor tek sorumluluk ilkesi ihlal ediliyor daha bir konudur.

O TDD tasarım kusurları açığa demektir, iyi bir şey. Ya bu hikaye gider.

Bu yöntemler kamu değildir ve sadece daha digestable parçalar halinde size kod parçalanıyor iseniz, dürüst, umurumda olmaz.

Bu yöntemler kamu iseniz, o zaman bir sorun var. Kural ardından, 'bir sınıf örneği herhangi bir kamu yöntemi, herhangi bir noktada çağrılabilir olmalı'. Yani yöntem çağrıları sipariş çeşit gerektiren iseniz, o zaman bu sınıf kırmak zamanı, söylemektir.