Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Laravel 在不影响PHP中私有属性的情况下部分模拟类_Laravel_Mocking_Phpunit_Mockery - Fatal编程技术网

Laravel 在不影响PHP中私有属性的情况下部分模拟类

Laravel 在不影响PHP中私有属性的情况下部分模拟类,laravel,mocking,phpunit,mockery,Laravel,Mocking,Phpunit,Mockery,我有一个包含很多方法的类,其中我只需要模拟一个方法,因为mysql和内存中的sqlite数据库之间存在一些sql不兼容 class OrderService implements OrderServiceContract { protected $deliveryService; public function __construct(Delivery $deliveryService) // DI injected object { ...

我有一个包含很多方法的类,其中我只需要模拟一个方法,因为mysql和内存中的sqlite数据库之间存在一些sql不兼容

class OrderService implements OrderServiceContract
{
    protected $deliveryService;

    public function __construct(Delivery $deliveryService) // DI injected object
    {
        ...
        $this->deliveryService = $deliveryService;
        ...
    }

    public function methodNeedstoBeMocked() 
    {
      ....some sql related code...
    }

    public function returnToWarehouse($orderId) 
    {
      DB::transaction(function() use ($orderId) {
         ...
         $this->deliveryService->someOtherMethod($orderId); // problematic external service call 
         ...
      });
    }

}
现在在我的测试中,我部分模拟了这个类,根据,我从测试中调用了returnToWarehouse,但它说

错误:调用成员函数returnToWarehouse时为空

这意味着属性$deliveryService在mock上不存在

我的测试实现如下

    /**
     * @test
     */
    public function an_order_can_be_returned_to_warehouse()
    {
        ...
        ...
        $this->partialMock(OrderService::class, function ($mock) {
            $mock->shouldReceive('methodNeedstoBeMocked')->andReturn(collect([]));
        });

        $orderService = app(OrderService::class);

        $orderService->markOrderReturnedToWarehouse($order->id); // here is the problem gets triggered.
        ...
        //assertions
    }

这里可能出了什么问题?有哪些方法可以缓解这种情况?提前感谢您的帮助。

通常,当我不得不模拟某些第三方服务时,我会设置这样的模拟

通过这种方式,您可以轻松设置DI服务

<?php
if (app()->environment('testing')) {

            $this->app->bind(Delivery::class, static function () {

                $service = \Mockery::mock(Delivery::class);

                $service->shouldReceive('someOtherMethod')->andReturn([]);

                return $service;
            });

        }

这里的问题是mockry中的部分测试加倍不会调用原始构造函数。有关更多信息,请阅读文档


或者,你可以考虑用不同的方法嘲弄有问题的方法。例如,您可以将该逻辑提取到存储库中,因为您提到它正在处理数据库层,然后可以在测试期间模拟该数据库层。

但它不是在模拟DeliveryService吗?我所做的是模拟OrderService类。还有,你建议我把这个放在哪里?在代码库或测试用例本身内部?嗨,我认为您也应该模拟DeliveryService,但也许我错了,我建议在TestClass的设置方法中添加该代码