Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preserve session through all tests on phpunit?

I'm working on testing a shopping cart, checkout, payment process on Zend Framework with phpunit. I'm testing ShoppingCartController by adding products to cart, a ShoppingCart Model handles product additions by storing product id's in a Zend Session Namespace, and then in another test I want to test that the products were added. The same ShoppingCart Model retrieves a list of added products from the same Zend Session namespace variable.

The add product test looks like this and works well, and the var_dump($_SESSION) was added to debug and shows the products correctly:

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);
}

The second test attempts to retrieve the products by asking the model to do so, the var_dump($_SESSION) is null already at the beginning of the test. The session variables were reset, I want to find a way to preserve them, can anyone help?

public function testCanDisplayShoppingCartWidget()  {
    var_dump($_SESSION);
    $this->dispatch($this->getRouteUrl("view_shopping_mini_cart"));
    $this->assertResponseCode('200');
}
like image 954
Daniel Avatar asked Feb 21 '12 01:02

Daniel


1 Answers

Sorry for pointing you in the wrong direction. Here is a way better way of achieving this, suggested by ashawley from #phpunit channel of irc.freenode.net:

<?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'] );
    }

}

?>

== END UPDATE

  1. In function tearDown(): copy $_SESSION to a class attribute and
  2. In function setUp(): copy the class attribute to $_SESSION

For example, this test fails when you remove the functions setUp() and tearDown() methods:

<?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'] ); 
    }  
}

Also there is a backupGlobals feature but it doesn't work for me. You should try it thought, maybe it works on stable PHPUnit.

like image 200
jpic Avatar answered Oct 29 '22 08:10

jpic