Session 如何在phpunit上的所有测试中保持会话?

Session 如何在phpunit上的所有测试中保持会话?,session,phpunit,Session,Phpunit,我正在用phpunit在Zend框架上测试购物车、结帐和付款流程。我正在通过向购物车添加产品来测试ShoppingCartController,一个ShoppingCart模型通过在Zend会话名称空间中存储产品id来处理产品添加,然后在另一个测试中,我想测试产品是否已添加。相同的ShoppingCart模型从相同的Zend会话名称空间变量检索添加的产品列表 add product测试如下所示,运行良好,var\u dump($\u SESSION)已添加到调试中,并正确显示了产品: publi

我正在用phpunit在Zend框架上测试购物车、结帐和付款流程。我正在通过向购物车添加产品来测试
ShoppingCartController
,一个
ShoppingCart
模型通过在Zend会话名称空间中存储产品id来处理产品添加,然后在另一个测试中,我想测试产品是否已添加。相同的
ShoppingCart
模型从相同的Zend会话名称空间变量检索添加的产品列表

add product测试如下所示,运行良好,
var\u dump($\u 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\u dump($\u SESSION)
在测试开始时已经为空会话变量已重置,我想找到一种保存它们的方法,有人能帮忙吗?

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

对不起,给你指错方向了。以下是实现这一目标的方法,由来自irc.freenode.net的#phpunit频道的ashawley建议:

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

}

?>

那样做很难看。正确的方法应该是使用依赖项注入

这意味着更改源代码以使用此类而不是直接使用会话:

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);
}
其他信息:


您也可以为PHPUnit测试创建一个随机会话id,然后确保在以后的每次调用中都通过cookie中的该会话id。对于Curl,您可以使用
CURLOPT\u COOKIE
选项,并将其设置为
'PHPSESSID=thesessionidofyourunittest'

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

我在中用一个例子作了更详细的解释。

您建议在测试用例之间共享会话吗?您可以制作一个SharedSessionTestCase,它扩展了PHPUnit_Framework_测试用例,并在那里定义$shared_会话、setUp()和tearDown()。然后,您可以有几个扩展SharedSessionTestCase的测试用例。我添加了一个更好的答案。好的,再次感谢。。我将尝试新的方法,并且肯定会尝试扩展PHPUnit_Framework_testcase绝对,这就是为什么我保留了最初的文章,这可能会有帮助。。。我们都将学习,这样即使对您的客户来说,这也是一个双赢的局面B)
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID=thesessionidofyourunittest');