为了账号安全,请及时绑定邮箱和手机立即绑定

使用 findOrFail 时获取“尝试获取非对象的属性'小计'”

使用 findOrFail 时获取“尝试获取非对象的属性'小计'”

PHP
波斯汪 2022-08-19 11:00:58
我在服务中有以下代码:public function add(array $data) : Order    {        // retrieve item data        $item       = MenuItem::findOrFail($data[OrderItem::ORDER_ITEM_ITEM_ID]);        $quantity   = $data[OrderItem::ORDER_ITEM_QUANTITY];        $order_no   = $data[Order::ORDER_NO] ?? null;        $session_id = $data[Order::ORDER_SESSION_ID];        $order = $order_no ? Order::findOrFail($order_no) : $this->createOrder([Order::ORDER_SESSION_ID => $session_id]);        $order_item = $this->order_item->createOrderItem($order->order_no, $item, $quantity);        // update order total        $order->subtotal += $order_item->subtotal;        $order->total    += $order_item->subtotal;        $order->update();        return $order;    }运行测试时,我得到:获取“尝试获取非对象的属性'小计'”检索到的对象不为空,否则它将失败。但是,小计和总计都不属于对象。如果我打印对象,我会得到除这两个字段之外的其他字段。它们都在我的数组中,我在迁移中定义了一个。$fillable->default(0);这是怎么回事?
查看完整描述

1 回答

?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

根据我们在评论中的对话,您在函数中遇到的问题之一,并因此导致测试中的问题,是一个依赖项,其中每次都无法保证结果。也就是说,对函数中另一个服务的调用不保证提供特定的输出。add

把你的测试想象成这样。

  • 我从零个项目和零小计的订单开始

  • 我想向该订单添加商品

  • 我想以一个包含一个项目的订单和一个十美元的小计结束

在此测试中,您不关心订单项的创建方式,您只关心它是否具有特定值,以便将其添加到订单中时,最终结果是您期望的。

在这种情况下,您希望成为一个模拟对象,然后您可以模拟调用以返回已知订单对象。向您展示一个完整的解决方案有点困难,因为它可能涉及一些架构更改,但您的测试将如下所示:$this->order_itemcreateOrderItem

public function it_adds_an_item_to_an_order()

{

  $orderItem = Mock(OrderItem::class); // Use whatever mocking lib is available

  $orderitem->shouldReceive('createOrderItem').andReturn(new OrderItem([$subtotal=>10.00]));

  $orderService = new OrderService($orderItem);


  $order = $orderService->add($data);


  $this->assertNotNull($order);

  $this->assertEquals(10.00, $order->subtotal);

}


查看完整回答
反对 回复 2022-08-19
  • 1 回答
  • 0 关注
  • 77 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信