How can I reference external data providers in phpunit?

左心房为你撑大大i 提交于 2019-12-22 10:37:01

问题


I am trying to run some tests using a common data provider in PHPUnit.

See below test:

    namespace AppBundle\Tests\Controller;

    use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
    use AppBundle\Tests\DataProvider\XmlDataProvider;

    class DefaultControllerTest extends WebTestCase
    {
        /**
         * @dataProvider XmlDataProvider::xmlProvider
         * @covers ReceiveController::receiveAction()
         * @param string
         */
        public function testReceive($xml)
        {
            $client = static::createClient([], ['HTTP_HOST' => 'mt.host']);
            $client->request(
                'POST',
                '/receive',
                [],
                [],
                [],
                $xml
            );

            $response = $client->getResponse();
            $this->assertEquals(200, $response->getStatusCode());
        }
    }

Now I want an external data provider class:

namespace AppBundle\Tests\DataProvider;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class XmlDataProvider extends WebTestCase
{
    /**
     * @dataProvider
     */
    public static function xmlProvider()
    {
        return array([
            'xml1' => '<?xml version="1.0" encoding="UTF-8"?><myTestableXml></myTestableXml>'
        ]);
    }
}

But when I run phpunit I get:

1) Warning The data provider specified for AppBundle\Tests\Controller\DefaultControllerTest::testReceive is invalid. Class XmlDataProvider does not exist

2) Warning No tests found in class "AppBundle\Tests\DataProvider\XmlDataProvider".

How do I do this?

UPDATE

composer.json autoload snippet for reference:

"autoload": {
    "psr-4": {
        "AppBundle\\": "src/AppBundle",
        "Tests\\": "tests"
    },
    "classmap": [
        "app/AppKernel.php",
        "app/AppCache.php"
    ]
},
"autoload-dev": {
    "psr-4": {
        "Tests\\": "tests/"
    },
    "files": [
        "vendor/symfony/symfony/src/Symfony/Component/VarDumper/Resources/functions/dump.php"
    ]
},

回答1:


You need to reference the data provider using the fully-qualified classname:

namespace AppBundle\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DefaultControllerTest extends WebTestCase
{
    /**
     * @dataProvider \AppBundle\Tests\DataProvider\XmlDataProvider::xmlProvider
     * @covers ReceiveController::receiveAction()
     * @param string $xml
     */
    public function testReceive($xml)
    {
        // ...
    }
}

Autoloading

Also, make sure to adjust your autoload configuration in composer.json, so the data provider can be autoloaded (might need adjustment depending on which directory the ’AppBundle\Test` namespace maps to):

{
    "autoload-dev": {
        "psr-4": {
            "AppBundle\\Tests\\": "tests/"
        }
    }
}

Alternatively, since you suggest your autoloading configuration looks like this:

{
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    }
}

you need to adjust your namespace for the presented tests from AppBundle\Tests to Tests\AppBundle.

Note Unrelated to your question, but personally, I can't see a need for the data provider to extend WebTestCase.

For examples, see:

  • https://github.com/refinery29/test-util#example
  • https://github.com/symfony/symfony-demo/blob/master/composer.json#L6-L16



回答2:


PHPUnit Provider Autoloader

Magic helper to autoload CSV, JSON, PHP, XML and YAML data provider in PHPUnit.

Instalation

composer require redaxmedia/phpunit-provider-autoloader

Usage

Create the TestCaseAbstract for your testing suite:

<?php
namespace ExampleProject\Tests;

use PHPUnitProviderAutoloader;

/**
 * TestCaseAbstract
 *
 * @since 2.0.0
 *
 * @package ExampleProject
 * @category Tests
 */

abstract class TestCaseAbstract extends PHPUnitProviderAutoloader\TestCaseAbstract
{
    /**
     * directory of the provider
     *
     * @var string
     */

    protected $_providerDirectory = 'tests' . DIRECTORY_SEPARATOR . 'provider';

    /**
     * namespace of the testing suite
     *
     * @var string
     */

    protected $_testNamespace = __NAMESPACE__;
}

Extend from TestCaseAbstract to autoload the ExampleTest{_testMethod}.{csv|json|php|xml|yml} file:

<?php
namespace ExampleProject\Tests;

/**
 * ExampleTest
 *
 * @since 2.0.0
 *
 * @package ExampleProject
 * @category Tests
 */

class ExampleTest extends TestCaseAbstract
{
    /**
     * testMethod
     *
     * @since 2.0.0
     *
     * @param string $expect
     *
     * @dataProvider providerAutoloader
     */

    public function testMethod(string $expect = null)
    {
        $this->assertEquals($expect, 'test');
    }
}

Read more

Related repository: https://github.com/redaxmedia/phpunit-provider-autoloader

Example integration: PHP test autoloads PHP class provider and PHP method provider



来源:https://stackoverflow.com/questions/45866365/how-can-i-reference-external-data-providers-in-phpunit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!