我不能让PHPUnit在我的代码上工作,它一直在说未定义的索引:ecs

I am working on a website using someone else's source code called ecshop, a e-commerce website. I want to use PHPUnit to unit test my code but meet a problem. This is what the error looks like:

C:\Users\maoqiuzi\Documents\Shanglian\XinTianDi\xintiandi\admin>phpunit --stderr wang_test.php PHPUnit 3.7.27 by Sebastian Bergmann.

E

Time: 1.03 seconds, Memory: 6.75Mb

There was 1 error:

1) ShopTest::test_get_shop_name Undefined index: ecs

C:\Users\maoqiuzi\Documents\Shanglian\XinTianDi\xintiandi\includes\lib_common.ph p:564 C:\Users\maoqiuzi\Documents\Shanglian\XinTianDi\xintiandi\admin\includes\init.ph p:147 C:\Users\maoqiuzi\Documents\Shanglian\XinTianDi\xintiandi\admin\wang.php:10 C:\Users\maoqiuzi\Documents\Shanglian\XinTianDi\xintiandi\admin\wang_test.php:10

FAILURES! Tests: 1, Assertions: 0, Errors: 1.

The source code of wang_test.php:

<?php
require_once("wang.php");
class ShopTest extends PHPUnit_Framework_TestCase
{
    public function test_get_shop_name()
    {
        $shop = new Wang();
        $first_row_of_shop_list = $shop->get_shop_list();
    }
}

The source code of wang.php:

<?php 
class Wang
{
    private $exchange;
        function get_shop_list()
        {
            define("IN_ECS", 1);
            require(dirname(__FILE__).'/includes/init.php');
            $this->exchange = new exchange($GLOBALS['ecs']->table('shop'), $GLOBALS['db'], 'shop_id', 'shop_name');
            $sql = "SELECT * FROM " . $GLOBALS['ecs']->table('shop');
            $shop_list = $GLOBALS['db']->getAll($sql);
            if($shop_list != array())
                return $shop_list;
            else
                return array();
        }
}

code in init.php

require(ROOT_PATH . 'includes/lib_common.php');
class ECS //line 82
{
    var $db_name = '';
    var $prefix  = 'ecs_';

    function ECS($db_name, $prefix)
    {
        $this->db_name = $db_name;
        $this->prefix  = $prefix;
    }
...
}
...
$ecs = new ECS($db_name, $prefix); // line 114
... // other initialization codes here
$_CFG = load_config(); //line 147

code in lib_common.php

function load_config()
{
    $arr = array();

    $data = read_static_cache('shop_config');
    if ($data === false)
    {
        $sql = 'SELECT code, value FROM ' . $GLOBALS['ecs']->table('shop_config') . ' WHERE parent_id > 0';
        $res = $GLOBALS['db']->getAll($sql);
...
}

I've been working on this for days, and felt very frustrated. Hope anyone help me out! Thanks!!!

As you can see in PHPunit's manual part related on "How to test for PHP errors", how error_reporting is configured affects the test suite; which is your case.

You have (at least) three different options:

  • Fix the code to check and not use undefined indexes of arrays
  • Change the error_reporting to ignore notices (one of the examples in the link)
  • Create (and use) a phpunit.xml configuration file and set convertNoticesToExceptions to false

In init.php, if you change:

$ecs = new ECS($db_name, $prefix);

to:

$GLOBALS['ecs'] = new ECS($db_name, $prefix);

does it start to work (or at least move on to a different error message)?

What I'm thinking is that init.php is expecting it is running as global code, so isn't being explicit like that, but then PHPUnit is doing something clever such that it is not run as global code. So $ecs just ends up being treated as a local variable, not as a global.

(If it does change the error message, go through all other global code in your libraries and change them to use $GLOBALS[...] explicitly too. This is a GoodThing™ to do anyway, as it makes code clearer when other people look at it, and avoids easy-to-make mistakes when refactoring global code into functions.)