2012-02-21 67 views
7

我正在使用phpunit測試Zend框架上的購物車,結帳,付款過程。我通過將產品添加到購物車來測試ShoppingCartControllerShoppingCart模型通過將產品ID存儲在Zend會話命名空間中來處理產品添加,然後在另一個測試中我想測試是否添加了產品。同一個ShoppingCart模型從相同的Zend會話命名空間變量中檢索添加產品的列表。如何通過phpunit上的所有測試來保存會話?

的附加產品的測試看起來是這樣的,並且效果很好,和var_dump($_SESSION)加入調試和正確顯示產品:通過詢問模型這樣做

public function testCanAddProductsToShoppingCart() { 

    $testProducts = array(
     array(
      "product_id" => "1", 
      "product_quantity" => "5" 
     ), 
     array(
      "product_id" => "1", 
      "product_quantity" => "3" 
     ), 
     array(
      "product_id" => "2", 
      "product_quantity" => "1" 
     ) 
    ); 

    Ecommerce_Model_Shoppingcart::clean(); 

    foreach ($testProducts as $product) { 
     $this->request->setMethod('POST') 
       ->setPost(array(
        'product_id' => $product["product_id"], 
        'quantity' => $product["product_quantity"] 
       )); 

     $this->dispatch($this->getRouteUrl("add_to_shopping_cart")); 
     $this->assertResponseCode('200'); 
    } 

    $products = Ecommerce_Model_Shoppingcart::getData(); 
    $this->assertTrue($products[2][0]["product"] instanceof Ecommerce_Model_Product); 
    $this->assertEquals($products[2][0]["quantity"], 
      "8"); 

    $this->assertTrue($products[2][1]["product"] instanceof Ecommerce_Model_Product); 
    $this->assertEquals($products[2][1]["quantity"], 
      "1"); 

    var_dump($_SESSION); 
} 

第二個測試嘗試檢索產品,在測試開始時var_dump($_SESSION)已經爲空。 會話變量被重置,我想找到一種方法來保存它們,任何人都可以幫忙嗎?

public function testCanDisplayShoppingCartWidget() { 
    var_dump($_SESSION); 
    $this->dispatch($this->getRouteUrl("view_shopping_mini_cart")); 
    $this->assertResponseCode('200'); 
} 

回答

6

對不起,指出你在錯誤的方向。

<?php 

# running from the cli doesn't set $_SESSION here on phpunit trunk 
if (!isset($_SESSION)) $_SESSION = array(); 

class FooTest extends PHPUnit_Framework_TestCase { 
    protected $backupGlobalsBlacklist = array('_SESSION'); 

    public function testOne() { 
     $_SESSION['foo'] = 'bar'; 
    } 

    public function testTwo() { 
     $this->assertEquals('bar', $_SESSION['foo']); 
    } 

} 

?> 

==結束時更新

  1. 在功能拆解():複製$ _SESSION來這裏是實現這一目標的a way better way,通過ashawley從irc.freenode.net的#phpunit通道建議一類屬性,
  2. 在功能設置():class屬性複製到$ _SESSION

例如,測試失敗,當你刪除功能設置()和tearDown()方法:

<?php 
# Usage: save this to test.php and run phpunit test.php  

# running from the cli doesn't set $_SESSION here on phpunit trunk                         
if (!isset($_SESSION)) $_SESSION = array(); 

class FooTest extends PHPUnit_Framework_TestCase { 
    public static $shared_session = array(); 

    public function setUp() { 
     $_SESSION = FooTest::$shared_session; 
    } 

    public function tearDown() { 

     FooTest::$shared_session = $_SESSION; 
    } 

    public function testOne() { 
     $_SESSION['foo'] = 'bar'; 
    } 

    public function testTwo() { 
     $this->assertEquals('bar', $_SESSION['foo']); 
    } 
} 

也有一個backupGlobals feature但它不爲我工作。你應該試試看,也許它在穩定的PHPUnit上工作。

+0

好吧,我試試吧 – Daniel 2012-02-21 13:21:48

+0

非常感謝,它按預期工作! – Daniel 2012-02-21 13:48:42

+0

你會建議什麼來分享會話測試用例? – Daniel 2012-02-21 14:10:32

1

這樣做很醜陋。正確的方法應該是使用依賴注入。

這意味着改變你的源代碼中使用這個類,而不是會議直接:

class Session 
{ 
    private $adapter; 
    public static function init(SessionAdapter $adapter) 
    { 
    self::$adapter = $adapter; 
    } 
    public static function get($var) 
    { 
     return self::$adapter->get($var); 
    } 
    public static function set($var, $value) 
    { 
    return self::$adapter->set($var, $value); 
    } 
} 

interface SessionAdapter 
{ 
    public function get($var); 
    public function set($var, $value); 
} 

其他信息:

0

你也可以創建一個隨機的會話ID對於您的PHPUnit測試,然後確保您在每次進一步的調用中都將該會話ID傳遞給cookie。隨着嫋嫋,你可以使用CURLOPT_COOKIE選項並將其設置爲'PHPSESSID=thesessionidofyourunittest'這樣:

$ch = curl_init($url); 
curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID=thesessionidofyourunittest'); 

我詳細地並在this stackoverflow answer爲例進行說明更多。