birim bir nesne oluşturur yöntem test

4 Cevap php

Ben yuvarlak Unit Testing başımı almak için çalışıyorum ve bulmak için gereken yapboz bir parçası daha var.

Ne yapmaya çalışıyorum aşağıdaki kodu testleri yazmak olduğunu. Bu durumda, ben (PHP ile yazılmış) gerçekten basit bir ön denetleyicisi var.

class frontController
{
   public function routeRequest($oRequest)
   {
      $sClassname = $oRequest->getController();
      $sMethod = $oRequest->getAction();

      $oController = new $sClassname();

      $oResponse = $oController->{$sMethod}($oRequest);

      return $oResponse;
   }

}

Ben sorun çünkü kod creates new objects. Ben kolayca mock isteği nesne ben sıkıca aslında benim test case içinde ne yapacağını kontrol edebilirsiniz böylece. Aslında bir test double ile controller değiştirmek için en iyi yolu, emin değilim.

This article from IBM zaman kontrol oluşturmak için bir yöntem olan fabrika ve daha sonra test için kullanılan bir specific sınıfı ile geçersiz göstermektedir:

class frontController
{
   public function routeRequest($oRequest)
   {
      $sMethod = $oRequest->getAction();

      $oController = $this->createController($oRequest);
      $oResponse = $oController->{$sMethod}($oRequest);

      return $oResponse;
   }

   protected function createController($oRequest)
   {
      $sClassname = $oRequest->getController();
      return new $sClassname();
   }

}

ve sonra bu gibi belki bir şey test için:

class testFrontController extends frontController
{
   public function setMockController($oMockController)
   {
      $this->oMc = $oMockController;
   }

   protected function createController($oRequest)
   {
      return $this->oMockController;
   }
}

(Bu madde diyor oldukça ne değildir unutmayın, ama ben bu yaptım eğer benim için en yararlı olacağını düşünüyorum)

Başka bir çözüm denetleyicisi oluşturan başka bir sınıf sahip olabilir. Bu daha sonra frontController bağımlı bir sınıf olacaktır. Bu şekilde ben bir test double ile test sırasında fabrika / oluşturma sınıfını değiştirebilirsiniz. Böyle bir şey:

class frontController
{
   public function routeRequest($oRequest, $oControllerFactory)
   {
      $sMethod = $oRequest->getAction();

      $oController = $oControllerFactory->create($oRequest);
      $oResponse = $oController->{$sMethod}($oRequest);

      return $oResponse;
   }
}

class controllerFactory
{
   public function create($oRequest)
   {
      $sClassname = $oRequest->getController();
      return new $sClassname();
   }
}

Ben bağımlılık enjeksiyon gerçek "rota" yöntemine ön kontrolör yapıcısı veya yerine bir parametrenin bir pasör yoluyla halledilir olabilir sanırım.

Ben 2. seçeneği tercih ederim.

Is either of these two methods the right way of going about testing this kind of thing?

(perhaps "good way" would be better word here!)

Seçenek 2 vs seçeneği 1 üzerinde herhangi bir düşünce ya da öneri aslında herhangi bir alternatifleri takdir ya. Unutmayın - anahtar şey hakkında nasıl test an object that itself creates other objects, yürütme parçası olarak.

Teşekkürler!

4 Cevap

Ben genellikle fabrikalar, bu senaryo için kullanılacak iyi bir şey olarak görüyorum. Swappability yönüne ek olarak, nesnenin oluşturulması için gerekli ek parametreler, veri veya bağımlılıkları fabrika tarafından saklanabilir ve böylece aslında yeni nesne ister nesne onlar hakkında hiçbir şey bilmek zorunda değildir anlamına gelir. ..

Sen this article kullanışlı bulabilirsiniz.

Bu nesne oluşturma uygulamasının fiili çalışan ayrılması gerektiğini anlatılır.

Haklısınız, gerçek denetleyicisi ama bir mock kullanmak istemiyorum?

Bu bir MockController adını döndürür böylece isteği alt sınıfı olacaktır ulaşmak için bana basit yolu görünüyor.

Ben tam olarak test şeyin hedefini tanımlamak için böylece iddialar üzerinden düşündüm varsayalım. Ünite testleri bu durumda, (bu ne olursa olsun) $ oResponse olduğunu yöntemlerinizi döner, test olacak unutmayın. Sonuç olarak, test iddialar bu dönüş değeri esas alınacaktır. Ben dönüş değeri kod parçacıkları gelen ne bilmiyorum, ben sadece tamamlayabilirsiniz bir örnek gösterebilir.

(Birçok yanı sıra, SimpleTest hayranları ... her biri kendi) PHP imho için en komple bir paket olarak görünüyor ben test için PHPUnit öneriyoruz.

(Ben kısalık için includes yapmamışlar unutmayın PHPUnit documentation daha fazla bilgi için okuyun.) Bu gibi bir şey olacaktır:

class AimTest extends PHPUnit_Framework_TestCase{
      private $_controller = null;
      private $_request = null;

      public function setUp(){
             $this->_controller = new frontController();
             //what does this object's type?
             $this->_request = new requestObject();  
      }

      public function testObjectCreation(){
            /*
             * note, that this is only one of several assertions that could
             * be made depending on the return value
             */
             $return = $this->_controller->routeRequest($this->_request);
             //tailor to what you expect your output to be
             $this->assertTrue($return == "my expected output");
      }

Ben sizin belirtilen amaç tamamen ıskalamak vermedi umuyoruz. Ahlaki hikayenin yalnızca yöntemleri dönmek ne test olabilir. Eğer bir yöntem nesne örnekleme test etmek istiyorsanız, örnekleme sonra o nesneyi döndüren bir yöntem karşı instanceof PHP işlevini kullanın.