【问题标题】:PHPUnit @dataProvider simply doesn't workPHPUnit @dataProvider 根本不起作用
【发布时间】:2012-04-27 20:36:59
【问题描述】:

我已阅读有关该主题的文档,并且我的代码遵循数据提供者实现的所有要求。首先,here's the full code of the test 以防万一。

这是实现数据提供者的函数:

/**
 * Test the createGroup function
 *
 * @return void
 * @author Tomas Sandven <tomas191191@gmail.com>
 *
 * @dataProvider provideFileImportTests_good
 **/
public function testCreateGroup($file, $groupname, $group, $mapping)
{
    // Create a test group
    $id = $this->odm->createGroup($groupname, $group);

    // Try to load it back out
    $result = R::load(OmniDataManager::TABLE_GROUP, $id);

    // Check that the result is not null
    $this->assertFalse(is_null($result));

    return $id;
}

PHPUnit 失败了:

tests\broadnet\broadmap\OmniDataManagerTest::testCreateGroup() 缺少参数 1

我尝试在数据提供程序函数中终止应用程序 (die();),但从未发生过。数据提供者函数在同一个类中公开可用,函数名称中没有拼写错误,testCreateGroup 函数在注释中的注释中引用了它,但从未调用数据提供者函数。

有人知道为什么吗?

【问题讨论】:

    标签: php phpunit


    【解决方案1】:

    最后,在对这个测试文件进行了数小时的测试后,我发现仅仅定义构造函数会破坏数据提供者的功能。很高兴知道。

    要修复它,只需调用父构造函数。这是我的情况:

    public function __construct()
    {
        // Truncate the OmniDataManager tables
        R::wipe(OmniDataManager::TABLE_GROUP);
        R::wipe(OmniDataManager::TABLE_DATA);
    
        parent::__construct();   // <- Necessary
    }
    

    正如David HarknessVasily 在cmets 中指出的那样,构造函数覆盖必须匹配基类构造函数的调用签名。在我的例子中,基类构造函数不需要任何参数。我不确定这是否在较新版本的 phpunit 中发生了变化,或者它是否取决于您的用例。

    无论如何,Vasily 的示例可能更适合您:

    public function __construct($name = null, array $data = array(), $dataName = '')
    {
        // Your setup code here
    
        parent::__construct($name, $data, $dataName)
    }
    

    【讨论】:

    • 你是否也调用了 parent::__constructor()?通常,无论如何您都不会为测试用例定义构造函数,而是使用 setUp() 函数。
    • 我需要在任何测试开始之前执行一次代码。不,我没有打电话给parent::__constructor()...我用function setUpBeforeClass 替换了构造函数。它必须是静态的,这是有问题的,但幸运的是我不需要在那里放任何花哨的东西
    • 你可以有一个自定义的构造函数,但你必须注意接受相同的参数并将它们传递给父构造函数。
    • parent::__constructor() 不是静态函数调用。
    • 就我而言,正如 David Harkness 所建议的那样,dataProvider 只有在我使自定义构造函数的签名与父构造函数相同后才开始工作 - public function __construct($name = null, array $data = array(), $dataName = '') 并将所有参数传递给 parent::__construct($name, $data, $dataName)。
    【解决方案2】:

    花了几个小时试图弄清楚 dataProvider 注释有什么问题。它根本没有被调用。

    就我而言,问题是 opcache。检查 php.ini 以确保 opcache.save_cmets 已启用:

    php -r "phpinfo();" | grep opcache.save_comments
    

    要启用它,请将其添加到 php.ini(或 /usr/local/php5/php.d/20-extension-opcache.ini,因为我正在使用来自 liip.ch 的 php for osx):

    [opcache]
    opcache.save_comments=1
    

    【讨论】:

      【解决方案3】:

      为了强调micro_user 提出的观点,@dataProvider 注释必须在文档块注释中。即这样做:

      /**
       * @dataProvider myDataProvider
       *
       */
      public function testMyMethod(...)
      {
        ...
      }
      

      不要这样做,因为它不起作用:

      /*
       * @dataProvider myDataProvider
       *
       */
      public function testMyMethod(...)
      {
        ...
      }
      

      【讨论】:

      • 你节省了一天
      • 很高兴听到这个消息。 :-)
      • 你又节省了一天:)
      • 在检查了我项目中的几乎所有内容之后......解决方案是如此接近和到目前为止;-) 非常感谢!
      【解决方案4】:

      对我来说,只有删除构造函数才有效。即使使用最新的稳定版本的 PHPUnit (6.0.9),在我的类测试中调用父构造函数也会破坏注释。

      我刚刚将 __constructor 上的代码移动到了在我的单元测试运行之前调用的 setUp 函数。

      【讨论】:

        【解决方案5】:

        你好,任何仍然从谷歌来到这里的人 :) 我正在使用 PHP 7.0.5 和 PHPUnit 5.3.2。

        正如@hubro 提到的——不要使用__construct(),因为它会破坏一些PHPUnit 注释。 Here 是一个带有更多细节的 SO 胎面。

        我的测试类 MyStuffTest 扩展 MyFancyTestcase 扩展 PHPUnit_Framework_TestCaseMyFancyTestcase 使用了__construct(),我得到了同样的错误。它应该使用setupBeforeClass() 而不是设置在所有测试用例之间共享的静态数据 - 数据库连接等,不需要__construct()。 DataProvider 现在可以工作了。

        【讨论】:

        • 首先,我不是说“不要使用__construct()”,我是说需要调用父函数,否则会破坏类的功能。此外,静态设置函数不能替代__construct() 的所有用例。
        【解决方案6】:

        确保 dataProvider 拼写正确...@dataProvidor vs @dataProvider

        在需要数据提供者的测试功能中,需要一个包含

        的文档块
        /**
        * @dataProvider providerItCanTest
        *//
        

        【讨论】:

        【解决方案7】:

        如果您真的需要它,David Harkness 有正确的提示。代码如下:

        public function __construct($name = NULL, array $data = array(), $dataName = '') {
            $this->preSetUp();
            parent::__construct($name, $data, $dataName);
        }
        

        【讨论】:

        • 这也专门为我解决了这个问题,没有参数调用 parent::construct() 没有。谢谢
        • 你是救生员!谢谢!
        • 这个构造函数是否定义在KernelAwareTest类中?
        【解决方案8】:

        该错误意味着您的 data-provider 方法返回的数据数组中至少有一个是空的。例如:

        public function dataProvider() {
            return array(
                array(1, 2, 3),
                array(),           // this will cause a "Missing argument 1" error
                array(4, 5, 6)
            );
        }
        

        由于您是动态生成数据数组,因此您需要调试数据源并找出会出现这种情况的原因。

        【讨论】:

        • 如果从未调用过,数据提供者如何返回一个空数据数组?
        • 我将提供程序函数复制到一个新的测试类中并且它工作。问题出在课堂上的其他地方
        • @Codemonkey:如果您给出的错误消息来自测试失败(我无法判断,因为您没有粘贴任何上下文),那么只有当数据集提供给测试方法为空。我能想到的让您收到此类错误消息的唯一其他方法将要求您尝试从代码中的某个位置自己手动调用testCreateGroup()(因此,不传递必要的参数),或者PHPUnit 调用的测试没有被视为具有数据提供者(这表明您的注释中有问题)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-28
        • 1970-01-01
        • 2017-05-16
        • 1970-01-01
        • 2013-11-05
        • 2011-02-20
        • 2011-06-25
        相关资源
        最近更新 更多