Laravel:不使用模拟方法进行测试

问题描述 投票:0回答:2

我希望

getNumber
在测试用例中返回
200
,但是当我运行测试并使用
$response->dump()
检查结果时,我可以看到模拟并没有覆盖显示
array:1 [0 => 100]
的方法。我错过了什么?

控制器:

class ServiceController extends Controller
{
    public function fetch(Request $request)
    {
        $service = new Service();
    
        return [$service->getNumber()];
    }
}

型号:

class Service extends Model
{
    public function getNumber(): int
    {
        return 100;
    }
}

测试:

class ControllerTest extends TestCase
{
    public function testFetchGetsNumber()
    {
        $mock = $this->partialMock(Service::class, function (MockInterface $mock) {
            $mock->shouldReceive('getNumber')->andReturn(200);
        });
    
        $response = $this->post('/api/controller');
        $response->dump(); // returns 100 but should return 200...
    }
}

我正在使用 Laravel 8 并引用此文档:https://laravel.com/docs/8.x/mocking#mocking-objects

php laravel phpunit laravel-8 mockery
2个回答
1
投票

Laravel
中,你必须使用容器来模拟类。

$service = resolve(Service::class);

在构造函数或句柄方法中,如果您在那里注入类,它将自动使用容器。如果放入构造函数或类中,请记住类与构造函数的解析,必须使用容器。

class Job 
{
    public function handle(Service $service)
    {
        // will use the mocked service.
    }
}

0
投票

问题是您的“服务”未注册到服务容器。

里面

AppServiceProvider.php
确保注册了你想要绑定的“服务”。

$this->instance->bind('service', ... );

在您的控制器中,不要使用

new
关键字实例化类,而是使用 Laravel 的
app()->make('service')

这将允许您在单元测试中模拟该类。在你的测试用例中..

 $this->app->bind('Service', $mock); 

© www.soinside.com 2019 - 2024. All rights reserved.