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'])
我在我的应用程序中执行单元测试,一些函数包括如下闭包函数:
<?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'])