【发布时间】:2026-01-30 20:00:01
【问题描述】:
我正在使用带有 php 单元的 laravel 5 来创建一个 laravel 包。我有一个Repository..
namespace Myname\Myapp\Repositories;
use Myname\Myapp\Models\PersonModel;
class PersonRepository
{
protected $personModel;
public function __construct(PersonModel $personModel)
{
$this->personModel = $personModel;
}
public function testFunction($var)
{
return $this->personModel->find($var);
}
}
..它实现了Model。
namespace Myname\Myapp\Models;
use Illuminate\Database\Eloquent\Model;
class PersonModel extends Model
{
protected $table = 'person';
}
Laravel IoC 自动将PersonModel 注入到PersonRepository 的构造函数中。
我正在编写一个单元测试,我想在其中使用 mockery 来模拟 PersonModel 模型,这样我就不会在测试期间访问数据库。
namespace Myname\Myapptests\unit;
use Mockery;
class PersonRepositoryTest extends \Myname\Myapptests\TestCase
{
/**
* @test
*/
public function it_returns_the_test_find()
{
$mock = Mockery::mock('Myname\Myapp\Models\PersonModel')
->shouldReceive('find')
->with('var');
$this->app->instance('Myname\Myapp\Models\PersonModel', $mock);
$repo = $this->app->make('Myname\Myapp\Repositories\PersonRepository');
$result = $repo->testFunction('var');
$this->assert...
}
}
当我运行测试时出现错误
1) 我的名字\Myapptests\unit\PersonRepositoryTest::it_returns_the_test_find ErrorException: 传递给 Myname\Myapp\Repositories\PersonRepository::__construct() 的参数 1 必须是 Myname\Myapp\Models\PersonModel 的实例,给定的 Mockery\CompositeExpectation 实例
根据我的阅读,mockery 扩展了它正在模拟的类,因此注入扩展类来代替类型提示的父级 (PersonModel) 应该没有问题
显然我错过了一些东西。其他示例将模拟对象显式注入到他们正在测试的类中。 Laravels IoC 正在(应该)为我做这件事。我必须绑定什么吗?
我有一种感觉,虽然模拟对象并没有以我认为的方式创建(扩展 PersonModel),否则我认为我不会看到这个错误。
【问题讨论】:
-
您可以尝试导入您的模型吗?你正在使用
PersonModel::class,但我没有看到use 'Myname\Myapp\Models\PersonModel' -
@FabioAntunes 更新了代码和错误输出
标签: php laravel phpunit mockery