sytez/data-object-tester

1.0.0 2021-10-26 20:30 UTC

This package is auto-updated.

Last update: 2024-09-27 02:47:43 UTC


README

PHPUnit PHPStan

数据对象测试器

你甚至应该对数据对象类进行单元测试吗?使用DataObjectTester,这变得如此轻松,你甚至不需要问自己这个问题!它自动化了不可变数据对象的PHPUnit测试。在一分钟内,你就会写出一个涵盖所有可能情况的测试。查看以下代码以了解它是如何工作的。

要求

  • PHP 8.0或更高版本
  • PHPUnit

安装

composer require sytzez/data-object-tester --dev

使用

考虑以下数据类

final class DataClass
{
    public function __construct(
        private string $string,
        private int $int,
        private array $array,
    ) {
    }

    public function getString(): string
    {
        return $this->string;
    }

    public function getInt(): int
    {
        return $this->int;
    }

    public function getArray(): array
    {
        return $this->array;
    }
}

为了确保getter方法始终返回给定的值,你所要做的只是编写一个继承自DataObjectTestCase的测试

use Sytzez\DataObjectTester\DataObjects\ClassExpectation
use Sytzez\DataObjectTester\DataObjectTestCase

class DataClassTest extends DataObjectTestCase
{
    /**
     * @test
     */
    public function it_returns_the_right_values(): void
    {
        $this->testDataObjects(
            ClassExpectation::create(DataClass::class, [
                'getString' => ['hello', 'world'],
                'getInt'    => [0, -1, PHP_INT_MAX],
                'getArray'  => [['a', 'b', 'c'], [1, 2, 3]],
            ])
        );
    }
}

(除了继承DataObjectTestCase之外,你也可以use TestsDataObjects)

这将测试所有getter是否存在,并且它们返回构造函数中提供的值。

类期望中的数组列出了getter,顺序与相应构造函数参数相同。对于每个属性,可以给出任意数量的可能值。测试器将使用这些值构建一些对象,并断言getter返回正确的值。

特性

测试可选参数

如果某个参数可以是可选的(有默认值),你可以使用DefaultPropertyCase来定义默认期望值。

use Sytzez\DataObjectTester\DataObjects\ClassExpectation
use Sytzez\DataObjectTester\PropertyCases\DefaultPropertyCase;

ClassExpectation::create(ValidatedDataClass::class, [
    'getNumber' => [
        1, 
        10,
        new DefaultPropertyCase(0),
    ],
]),

测试验证异常

如果在实例化过程中传递某些值应导致错误或异常被抛出,请使用ConstructorExceptionPropertyCase。所以如果你的构造函数看起来像这样

public function __construct(
    private int $number,
) {
    if ($this->number < 0) {
        throw new \InvalidArgumentException('Number cannot be negative');
    }
}

你可以这样测试它

use Sytzez\DataObjectTester\DataObjects\ClassExpectation
use Sytzez\DataObjectTester\PropertyCases\ConstructorExceptionPropertyCase;

ClassExpectation::create(ValidatedDataClass::class, [
    'getNumber' => [
        1, 
        10,
        new ConstructorExceptionPropertyCase(-1, 'Number cannot be negative'),
    ],
]),

如果多个参数应引发异常,测试将断言可能抛出的异常之一。

测试转换属性

如果你的数据类以某种方式更改传入的值,你可以在类期望中使用TransformativePropertyCase类。

假设你的getter看起来像这样

public function getString(): string
{
    return ucfirst($this->string);
}

然后你可以这样编写类期望

use Sytzez\DataObjectTester\DataObjects\ClassExpectation
use Sytzez\DataObjectTester\PropertyCases\TransformativePropertyCase;

ClassExpectation::create(TransformativeDataClass::class, [
    'getString' => [
        new TransformativePropertyCase('hello', 'Hello'),
        new TransformativePropertyCase('world', 'World'),
    ],
]),

使用闭包进行测试

你可以使用ClosurePropertyCase通过编写一个返回bool的闭包来自定义getter输出的验证。示例

use Sytzez\DataObjectTester\PropertyCases\ClosurePropertyCase;

ClassExpectation::create(AcmeClass::class, [
    'getCollection' => new ClosurePropertyCase(
        new ArrayCollection([1, 2, 3]),
        static fn (Collection $output): bool =>
            $output->contains(1)
            && $output->contains(2)
            && $output->contains(3)
    ),
])

测试用例生成器

默认情况下,会创建最小数量的对象,涵盖每个指定的属性值至少一次。但如果你希望涵盖所有可能的属性值组合,你可以使用MaximalCaseGenerator,通过将其作为testDataObjects的第二个参数传递,如下所示

use Sytzez\DataObjectTester\Generators\MaximalCaseGenerator

$this->testDataObjects(
    ClassExpectation::create(DataClass::class, [
        'getString' => ['hello', 'world'],
        'getInt'    => [0, -1, PHP_INT_MAX],
        'getArray'  => [['a', 'b', 'c'], [1, 2, 3]],
    ]),
    new MaximalCaseGenerator()
);

在这种情况下,将实例化并测试12(2 * 3 * 2)个对象,而不是3个案例的最小值。

你可以通过向生成器提供一个参数来限制对象数量,例如new MaximalCaseGenerator(20)。默认限制为100。

你还可以提供自己的案例生成器,通过实现CaseGeneratorStrategy

特殊案例

如果某个案例尚未(尚未)由包覆盖,你当然还可以向测试用例添加自己的@test方法。

代码质量

单元测试

该项目使用PHPUnit实现了100%的行测试覆盖率。

PHPStan

PHPStan在最大级别8上报告了0个错误。

许可

MIT许可证(MIT)。请参阅许可文件获取更多信息。