draw/tester

基于phpunit的库,以流畅的接口测试您的数据。

0.10.47 2024-09-25 20:25 UTC

This package is auto-updated.

Last update: 2024-09-25 20:27:16 UTC


README

此包提供了一组工具,帮助您测试您的应用程序。

数据测试器

此库是围绕 PHPUnit Assert 类的包装,以便能够在您要测试的数据上使用流畅的接口。

以下是一个如何在 PHPUnit TestCase 中使用它的快速示例

namespace Your\Project\Name;

use PHPUnit\Framework\TestCase;
use Draw\Component\Tester\DataTester;

class SimpleTest extends TestCase
{
    public function test()
    {
        $data = [
          'key1' => 'value1',
          'key2' => (object)['toto' => 'value']
        ];

        $dateTester = new DataTester($data);
        $dateTester
            ->assertIsArray('array')
            ->assertCount(2)
            ->path('[key1]')->assertSame('value1');
            
        $dateTester->path('[key2].toto')->assertSame('value');
    }
}

PHPUnit 扩展

此包还提供了一个PHPUnit扩展,使编写测试更容易。

CarbonReset

如果您在项目中使用Carbon,您可能希望在每个测试之间重置Carbon类,以确保您有一个一致的状态。

在您的PHPUnit配置文件中注册该扩展。

<phpunit bootstrap="vendor/autoload.php">
    <extensions>
        <bootstrap class="Draw\Component\Tester\PHPUnit\Extension\CarbonReset\CarbonResetExtension"/>
    </extensions>
</phpunit>

这将像在 TestCass::tearDownTestCass::tearDownAfterClass 中那样在每个测试和测试套件之间重置您的Carbon类。

SetUpAutowire

与通过服务容器工作的服务自动注入类似,此扩展允许您根据实现 AutowireInterface 的属性自动注入属性。

请确保在您的PHPUnit配置文件中注册它。

<phpunit bootstrap="vendor/autoload.php">
    <extensions>
        <bootstrap class="Draw\Component\Tester\PHPUnit\Extension\SetUpAutowire\SetUpAutowireExtension"/>
    </extensions>
</phpunit>

完成后,您的测试需要实现 AutowiredInterface 接口,以便扩展可以挂钩。

namespace App\Tests;

use Draw\Component\Tester\PHPUnit\Extension\SetUpAutowire\AutowiredInterface;use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class MyTest extends KernelTestCase implements AutowiredInterface
{
}

仅扩展本身并没有什么作用,您需要在需要自动注入的属性上放置一些属性。

请注意,自动注入系统不适用于静态属性。

namespace App\Tests;

use App\MyInterface;
use App\MyObject;
use App\MySecondObject;
use Draw\Component\Tester\PHPUnit\Extension\SetUpAutowire\AutowiredInterface;
use Draw\Component\Tester\PHPUnit\Extension\SetUpAutowire\AutowireMock;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class MyTest extends TestCase implements AutowiredInterface
{
   // Will create a mock object of MyInterface and assigned it to property.
   // This can be used in conjunction with the AutowireMockProperty (see below).
   #[AutowireMock]
   private MyInterface&MockObject $aService
   
   // The AutowireMockProperty will replace the aService property of $myObject. 
   #[AutowireMockProperty('aService')]
   private MyObject $myObject;
   
   // By defaults, it will use the same property name in the current test case, but you can specify a different one using the second parameter.
   #[AutowireMockProperty('aService', 'anotherProperty')]
   private MySecondObject $mySecondObject;
   
   public function setUp(): void
   {
       $this->myObject = new MyObject();
       $this->mySecondObject = new MySecondObject();
   }
}

这可能看起来有点无意义,但在框架环境中使用服务时将更有意义。《AutowireService》从 draw/tester-bundle 是在Symfony中实现此功能的良好示例。

由于自动注入是在phpunit扩展的 setUp 插件中完成的,因此您不能在测试的设置方法中使用它们。如果您需要在 setUp 方法中访问这些属性,则可以使用 AutowiredCompletionAwareInterface

namespace App\Tests;

use App\MyService;use Draw\Bundle\TesterBundle\PHPUnit\Extension\SetUpAutowire\AutowireService;use Draw\Component\Tester\PHPUnit\Extension\SetUpAutowire\AutowiredCompletionAwareInterface;use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class MyTest extends KernelTestCase implements AutowiredCompletionAwareInterface
{
   #[AutowireMock]
   private MyInterface&MockObject $aService
   
    public function postAutowire(): void
    {
         $this->aService
            ->expects(static::any())
            ->method('someMethod')
            ->willReturn('someValue');
    }
}

创建自己的自动注入属性

您可以创建自己的属性来自动注入自己的属性。

您只需要创建一个实现 AutowireInterface 接口的属性。

namespace App\Test\PHPUnit\SetUpAutowire;

use Draw\Component\Tester\PHPUnit\Extension\SetUpAutowire\AutowireInterface;use PHPUnit\Framework\TestCase;

#[\Attribute(\Attribute::TARGET_PROPERTY)]
class AutowireRandomInt implements AutowireInterface
{
    // This is the priority of the autowire. The higher the number the sooner it will be called.
    // This can be important if you need to autowire a property before another one.
    public static function getPriority(): int
    {
        return 0;
    }

    public function __construct(
       private int $min = \PHP_INT_MIN, 
       private int $max = \PHP_INT_MAX
    ) {}

    public function autowire(TestCase $testCase, \ReflectionProperty $reflectionProperty): void
    {
        $reflectionProperty->setValue(
            $testCase,
            random_int($this->min, $this->max)
        );
    }
}

现在您可以在测试用例中简单地使用它了

namespace App\Tests;

use App\Test\PHPUnit\SetUpAutowire\AutowireRandomInt;

class MyTest extends KernelTestCase
{
    #[AutowireRandomInt(1, 10)]
    private int $randomInt;
}