如何通过phpunit上的所有测试保留会话?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过phpunit上的所有测试保留会话?相关的知识,希望对你有一定的参考价值。
我正在使用phpunit测试Zend Framework上的购物车,结帐,付款流程。我正在通过向购物车添加产品来测试ShoppingCartController
,ShoppingCart
模型通过将产品ID存储在Zend会话命名空间中来处理产品添加,然后在另一个测试中我想测试产品是否已添加。相同的ShoppingCart
Model从同一个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)
在测试开始时已经为空。会话变量被重置,我想找到一种方法来保存它们,任何人都可以帮忙吗?
public function testCanDisplayShoppingCartWidget() {
var_dump($_SESSION);
$this->dispatch($this->getRouteUrl("view_shopping_mini_cart"));
$this->assertResponseCode('200');
}
很抱歉指向错误的方向。以下是来自irc.freenode.net的#phpunit频道的ashawley建议实现此目的的a way better way:
<?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
- 在函数tearDown()中:将$ _SESSION复制到类属性和
- 在函数setUp()中:将class属性复制到$ _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 feature但它对我不起作用。你应该试一试,也许它适用于稳定的PHPUnit。
这样做非常难看。正确的方法应该是使用依赖注入。
这意味着更改源代码以直接使用此类而不是会话:
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);
}
附加信息:
- http://community.sitepoint.com/t/phpunit-testing-cookies-and-sessions/36557/2
- Using PHPUnit to test cookies and sessions, how?
您也可以为PHPUnit测试创建一个随机会话ID,然后确保在每次进一步调用时在cookie中传递此会话ID。使用Curl,您将使用CURLOPT_COOKIE
选项并将其设置为'PHPSESSID=thesessionidofyourunittest'
:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID=thesessionidofyourunittest');
我在this stackoverflow answer中详细解释了一些例子。
以上是关于如何通过phpunit上的所有测试保留会话?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过phpunit对一个方法进行单元测试,该方法具有多个内部调用保护/私有方法?
Laravel 路由上的 PHPunit 测试总是返回 404