refinery29/test-util

Provides a test helper, generic data providers, and assertions.

0.11.4 2017-06-02 17:22 UTC

README

Build Status Code Climate Test Coverage Issue Count Latest Stable Version Total Downloads

Provides a test helper, generic data providers, and assertions.

Installation

Run:

$ composer require refinery29/test-util

Usage

Test Helper

If you want to make use of the test helper, import the Refinery29\Test\Util\TestHelper trait!

namespace Acme\Test;

use PHPUnit\Framework;
use Refinery29\Test\Util\TestHelper;


final class WebsiteTest extends Framework\TestCase
{
    use TestHelper;
}

Additional Assertions

The test helper provides a few assertions:

  • assertClassesAreAbstractOrFinal($path, array $excludeDirectories = [])
  • assertClassesSatisfy(callable $specification, $path, array $excludeDirectories = [])
  • assertFinal($className)
  • assertExtends($parentClassName, $className)
  • assertImplements($interfaceName, $className)
assertClassesSatisfy(callable $specification, $path, array $excludeDirectories = [])

The callable will be passed in an instance of ReflectionClass which can be used for further introspection, and should return a bool, indicating that the specification is satisfied.

For example:

$this->assertClassesSatisfy(
    function (\ReflectionClass $reflection) {
        return false !== \strpos('MySmallClass', $reflection->getName());
    },
    __DIR__
);

Generating fake data using Faker

Lazily fetch an instance of Faker\Generator (see fzaninotto/faker) using

  • getFaker($locale = 'en_US') : \Faker\Generator

Providing data from an array of values

Quickly provide data from an array of values, using

  • provideData(array $data) : \Generator

Providing data from multiple concrete data providers

Quickly provide data from multiple concrete data providers using

  • provideDataFrom(...$dataProviders) : \Generator

Providing combination of data from multiple concrete data providers

Quickly combine data from multiple concrete data providers using

  • provideCombinedDataFrom(...$dataProviders) : array

Data Providers

If you need to assert that invalid values are rejected, you can use one of the data providers:

  • Refinery29\Test\Util\DataProvider\BlankString
  • Refinery29\Test\Util\DataProvider\InvalidBoolean
  • Refinery29\Test\Util\DataProvider\InvalidBooleanNotNull
  • Refinery29\Test\Util\DataProvider\InvalidFloat
  • Refinery29\Test\Util\DataProvider\InvalidFloatNotNull
  • Refinery29\Test\Util\DataProvider\InvalidInteger
  • Refinery29\Test\Util\DataProvider\InvalidIntegerNotNull
  • Refinery29\Test\Util\DataProvider\InvalidIntegerish
  • Refinery29\Test\Util\DataProvider\InvalidIntegerishNotNull
  • Refinery29\Test\Util\DataProvider\InvalidIsoDate
  • Refinery29\Test\Util\DataProvider\InvalidIsoDateNotNull
  • Refinery29\Test\Util\DataProvider\InvalidJsonString
  • Refinery29\Test\Util\DataProvider\InvalidNumeric
  • Refinery29\Test\Util\DataProvider\InvalidNumericNotNull
  • Refinery29\Test\Util\DataProvider\InvalidScalar
  • Refinery29\Test\Util\DataProvider\InvalidScalarNotNull
  • Refinery29\Test\Util\DataProvider\InvalidString
  • Refinery29\Test\Util\DataProvider\InvalidStringNotNull
  • Refinery29\Test\Util\DataProvider\InvalidUrl
  • Refinery29\Test\Util\DataProvider\InvalidUrlNotNull
  • Refinery29\Test\Util\DataProvider\InvalidUuid
  • Refinery29\Test\Util\DataProvider\InvalidUuidNotNull

If you need generic values, you can use one of the data providers

  • Refinery29\Test\Util\DataProvider\Boolean
  • Refinery29\Test\Util\DataProvider\EmptyValue
  • Refinery29\Test\Util\DataProvider\Falsy
  • Refinery29\Test\Util\DataProvider\Scalar
  • Refinery29\Test\Util\DataProvider\Truthy

If you want to mix data providers above with some arbitrary values, use

  • Refinery29\Test\Util\DataProvider\Elements

Example

Putting it all together, here's an example of a test making use of the test helper:

namespace Acme\Test;

use Acme\Website;
use PHPUnit\Framework;
use Refinery29\Test\Util\DataProvider;
use Refinery29\Test\Util\TestHelper;

final class WebsiteTest extends Framework\TestCase
{
    use TestHelper;

    /**
     * @dataProvider providerInvalidTitle
     * 
     * @param mixed $title
     */
    public function testConstructorRejectsInvalidTitle($title)
    {
        $this->expectException(\InvalidArgumentException::class);
        
        new Website($title);
    }
    
    /**
     * @return \Generator
     */
    public function providerInvalidTitle()
    {
        return $this->provideDataFrom(
            new DataProvider\InvalidString(),
            new DataProvider\BlankString(),
            new DataProvider\Elements([
                'foo',
                'bar',
            ])
        );
    }
    
    public function testConstructorSetsTitle()
    {
        $title = $this->getFaker()->sentence();
        
        $website = new Website($title);
        
        $this->assertSame($title, $website->title());
    }
    
    /**
     * @dataProvider \Refinery29\Test\Util\DataProvider\InvalidUrl::data()
     * 
     * @param mixed $url
     */
    public function testWithUrlRejectsInvalidUrl($url)
    {
        $title = $this->getFaker()->sentence();
        
        $website = new Website($title);
        
        $this->expectException(\InvalidArgumentException::class);
        
        $website->withUrl($url);
    }
    
    /**
     * @dataProvider providerUrl
     * 
     * @param string $url
     */
    public function testWithUrlClonesInstanceAndSetsUrl($url)
    {
        $title = $this->getFaker()->sentence();
        
        $website = new Website($title);
        
        $mutated = $website->withUrl($url);
        
        $this->assertInstanceOf(Website::class, $mutated);
        $this->assertNotSame($website, $mutated);
        $this->assertSame($url, $mutated->url());
    }
 
    /**
     * @return \Generator
     */
    public function providerUrl()
    {
        return $this->provideData([
            'http://www.refinery29.com',
            'http://www.refinery29.de',
            'http://www.refinery29.uk',
        ]);
    }
}

Contributing

Please have a look at CONTRIBUTING.md.

Code of Conduct

Please have a look at CONDUCT.md.

License

This package is licensed using the MIT License.