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

发布于 2025-01-07 07:24:27 字数 1965 浏览 0 评论 0原文

我正在使用 phpunit 在 Zend Framework 上测试购物车、结帐、付款流程。我正在通过将产品添加到购物车来测试 ShoppingCartControllerShoppingCart 模型通过将产品 id 存储在 Zend 会话命名空间中来处理产品添加,然后在我想测试的另一个测试中产品已添加。相同的 ShoppingCart 模型从相同的 Zend Session 命名空间变量中检索添加的产品列表。

添加产品测试如下所示并且运行良好,并且添加了 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) 在测试开始时就已经为 null。 会话变量已重置,我想找到一种方法来保留它们,有人可以帮忙吗?

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橙幽之幻 2025-01-14 07:24:27

抱歉给您指出了错误的方向。这是实现此目标的更好方法 ,由 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'] );
    }

}

?>

== END UPDATE

  1. 在函数tearDown() 中:将 $_SESSION 复制到类属性并
  2. 在函数中setUp():将类属性复制到 $_SESSION

例如,当您删除函数 setUp() 和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 功能 但它对我不起作用。你应该尝试一下,也许它可以在稳定的 PHPUnit 上运行。

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.

清晨说晚安 2025-01-14 07:24:27

这样做是非常丑陋的。正确的方法应该是使用依赖注入。

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

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

附加信息:

that's a very ugly of doing that. The right way should be using dependency injection.

That implies changing your source code to use this class instead of sessions directly:

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

Additional information:

池木 2025-01-14 07:24:27

您还可以为 PHPUnit 测试创建一个随机会话 ID,然后确保在每次进一步调用时在 Cookie 中传递此会话 ID。对于 Curl,您可以使用 CURLOPT_COOKIE 选项并将其设置为 'PHPSESSID=thesessionidofyourunittest',如下所示:

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

我在 这个 stackoverflow 答案

You can also just create a random session id for your PHPUnit test, and then make sure you pass this session id in a cookie in every further call you make. With Curl, you would use the CURLOPT_COOKIE option and set it to 'PHPSESSID=thesessionidofyourunittest' as such:

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

I explained more in detail and with an example in this stackoverflow answer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文