a-6ren">
gpt4 book ai didi

php - 如何测试 Laravel 5.4 中的 "creating"事件是否调用了 Eloquent 模型方法?

转载 作者:行者123 更新时间:2023-11-28 20:13:54 25 4
gpt4 key购买 nike

我想测试当 eloquent event 时是否调用了一个方法被触发。

在下面的示例中,当 Student 实例保存到数据库。

这是Student模型类:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Student extends Model
{

public $guarded = [];


protected static function boot()
{
parent::boot();

// set approved attribute if its value is NULL
self::creating(function (self $student) {
$student->approved = $student->approved ?? $student->isApproved();
});
}

/**
* @return bool
*/
public function isApproved()
{
return ($this->age >= 14) && ($this->age <= 20);
}
}

为了实现这一点,我在 Student 类的 creating 事件上附加了一个回调函数。

我正在尝试使用以下测试来测试 isApproved() 方法调用:

<?php

namespace Tests\Feature;

use App\Student;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class StudentTest extends TestCase
{

use DatabaseMigrations;

/**
* @test
*/
public function student_is_auto_approved_on_save()
{

$mock = \Mockery::mock(Student::class);
$mock->shouldReceive('isApproved')->once();

Student::create([
'name' => 'John Doe',
'age' => 14
]);
}
}

但是测试没有通过并且显示了下面的转储

    PHPUnit 5.7.21 by Sebastian Bergmann and contributors.

E 1 / 1 (100%)

Time: 246 ms, Memory: 16.00MB

There was 1 error:

1) Tests\Feature\StudentTest::student_is_auto_approved_on_save
Mockery\Exception\InvalidCountException: Method isApproved() from Mockery_0_App_Student should be called
exactly 1 times but called 0 times.

/students/vendor/mockery/mockery/library/Mockery/CountValidator/Exact.php:37
/students/vendor/mockery/mockery/library/Mockery/Expectation.php:298
/students/vendor/mockery/mockery/library/Mockery/ExpectationDirector.php:120
/students/vendor/mockery/mockery/library/Mockery/Container.php:297
/students/vendor/mockery/mockery/library/Mockery/Container.php:282
/students/vendor/mockery/mockery/library/Mockery.php:152
/students/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:144
/home/user/.composer/vendor/phpunit/phpunit/src/TextUI/Command.php:186
/home/user/.composer/vendor/phpunit/phpunit/src/TextUI/Command.php:116

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

我做错了什么?

最佳答案

尝试

<?php

namespace Tests\Feature;

use App\Student;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class StudentTest extends TestCase
{
use DatabaseMigrations;

/**
* @test
* @dataProvider providerAutoApprovedAge
*
* @param int $age
*/
public function student_is_auto_approved_on_save($age)
{
$student = Student::create([
'name' => 'John Doe' . $age,
'age' => $age,
]);

$student->save();

$this->assertTrue($student->approved);
}

public function providerAutoApprovedAge()
{
for ($age = 14; $age <= 20; $age++) {
yield [
$age,
];
}
}

/**
* @test
* @dataProvider providerNotAutoApprovedAge
*
* @param int $age
*/
public function student_is_not_auto_approved_on_save($age)
{
$student = Student::create([
'name' => 'John Doe' . $age,
'age' => $age,
]);

$student->save();

$this->assertFalse($student->approved);
}

public function providerNotAutoApprovedAge()
{
for ($age = 0; $age < 14; $age++) {
yield [
$age,
];
}

for ($age = 21; $age < 120; $age++) {
yield [
$age,
];
}
}
}

你可能想断言学生是

  • 自动批准要求年龄范围内的年龄
  • 不会自动批准超出规定年龄范围的年龄

您可以为此使用数据提供程序。

或者,您可以这样 stub 该方法:

class StudentStub extends Student
{
public $hasApprovedBeenInvoked = false;

public function isApproved()
{
$this->hasApprovedBeenInvoked = true;
}
}

class StudentTest extends TestCase
{
use DatabaseMigrations;

/**
* @test
*/
public function student_is_auto_approved_on_save($age)
{
$student = StudentStub::create([
'name' => 'John Doe' . $age,
'age' => $age,
]);

$student->save();

$this->assertTrue($student->hasApprovedBeenInvoked);
}
}

但是,这仅在 Student::create() 使用后期静态绑定(bind)并返回 StutentStub 的实例时才有效。

而且大多数情况下,您不想模拟被测系统,而是模拟协作者(如果有的话)。在这里,没有。

引用,见

关于php - 如何测试 Laravel 5.4 中的 "creating"事件是否调用了 Eloquent 模型方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45035826/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com