PHP 单元测试闭包函数

PHP Unit Test Closure functions

我在我的应用程序中执行单元测试,一些函数包括如下闭包函数:

<?php

namespace JobProgress\Transformers;
use League\Fractal\TransformerAbstract;
class CustomersTransformer extends TransformerAbstract {
    
    public function includesCreatedBy($customer) {
         $user = $customer->createdBy;
         if($user) {
              return $this->item($user, function($user){
                 \Log::info('unit test');
                  return [
                    'id'               => (int)$user->id,
                    'first_name'       => $user->first_name,
                    'last_name'        => $user->last_name,
                    'full_name'        => $user->full_name,
                    'full_name_mobile' => $user->full_name_mobile,
                    'company_name'     => $user->company_name,
                 ];
             });
         }
    }
}

注意:我扩展了 Fractal 的 TransformerAbstract class 并使用 item 函数作为 TransformerAbstract class.

中的 $this->item

这是我执行测试的方式:

public function testIncludeDeletedBy() {
        $customer = factory(Customer::class)->create();
        $include = $this->transformer->includesCreatedBy($customer);
        $object = $include->getData()->first();
        $this->assertInstanceOf(User::class, $object);
}

我的单元测试没有执行我在闭包函数中编写的代码。 就像我在上面的代码中提到的,我添加了一些日志,但是我的单元测试没有执行那部分代码。

谁能帮帮我

这可能与$this->item()方法的实现细节有关。你可能期望闭包被执行,而正如我们所见,闭包只需要被解析,然后作为参数传递给方法。

该代码没有显示它实际执行的内容,因此您不应期望它会是这样,因为它是一个未在您测试下的实现细节。

您可以 de-anonymize 闭包并直接调用它以便能够将其作为一个单元进行测试。

因此,您对现有方法中的 if-clause 进行了一项测试,而另一项测试允许您 运行 (不仅解析)您当前拥有的代码作为匿名函数/闭包。

这有时称为 test-point,可以提高您的速度。单元越小,越容易测试。

<?php

namespace JobProgress\Transformers;
use League\Fractal\TransformerAbstract;
class CustomersTransformer extends TransformerAbstract {
    
    public function includesCreatedBy($customer) {
         $user = $customer->createdBy;
         if($user) {
              return $this->item($user, $this->transformImplementation(...));
         }
    }

    public function transformImplementation(object $user) {
        \Log::info('unit test');
        return [
            'id'               => (int)$user->id,
            'first_name'       => $user->first_name,
            'last_name'        => $user->last_name,
            'full_name'        => $user->full_name,
            'full_name_mobile' => $user->full_name_mobile,
            'company_name'     => $user->company_name,
        ];
    }
}

对于三个点 (...),这是 PHP 8.1 语法,比较 PHP RFC: First-class callable syntax 替代 PHP 8.1 之前的语法 callables,例如:

Closure::fromCallable([$this, 'transformImplementation'])