【发布时间】:2018-05-03 05:51:14
【问题描述】:
我是测试和编写可测试代码的新手,我正在寻找有关处理这个简单场景的正确方法的一些说明。我已经阅读了关于 SO 的其他类似标题的问题和答案,但它们似乎没有为我的问题提供明确的答案。
我有一个控制器,它在我的 Picking 类的实例上调用 shipped() 方法:
class MyController extends \BaseController {
public function controllerMethod() {
$picking = new Picking;
$picking->shipped($shipmentData);
}
}
Picking 模型如下所示:
class Picking extends \Eloquent {
public function order() {
return $this->belongsTo('Order');
}
public function shipped($shipmentData) {
$this->carrier = $shipmentData['Carrier'];
$this->service = $shipmentData['Service'];
$this->is_shipped = true;
$this->save();
$this->order->pickingShipped();
}
}
如你所见,这个shipped()方法保存了一些数据,然后调用pickingShipped()方法,在它的相关Order上。
现在,我正在尝试为 shipped() 方法编写测试,但我不确定执行此操作的适当方法。我读过关于模拟的文章,但如果这是需要模拟的情况,我会感到困惑。我已经想到了一些可能的解决方案,但我不确定它们是否正确。
1) 重新排列代码,以便控制器调用pickingShipped() 方法,允许将其从shipped() 方法中删除,从而简化测试。
例如,shipped() 方法的最后一行将被删除,控制器代码将更改为:
$picking = new Picking;
$picking->shipped($shipmentData);
$picking->order->pickingShipped();
2) 在测试中,对order 使用模拟方法,以便测试可以简单地确认pickingShipped() 方法被调用。
类似于here 解释的内容。这意味着测试可以做这样的事情:
$order->expects($this->once())->method('pickingShipped')
但是,我认为这意味着我还需要注入订单依赖项,而不是依赖 shipped() 方法中的 order 关系,如下所示:
class Picking extends \Eloquent {
public function order() {
return $this->belongsTo('Order');
}
public function shipped(Order $order, $shipmentData) {
$this->carrier = $shipmentData['Carrier'];
$this->service = $shipmentData['Service'];
$this->is_shipped = true;
$this->save();
$order->pickingShipped();
}
}
然后控制器中的代码必须如下所示:
$picking = new Picking;
$picking->shipped($picking->order, $shipmentData);
这感觉有点奇怪,但我真的不确定什么是对的。
我的问题是,编写和测试这段代码的正确方法是什么?很容易测试 shipped() 方法在其自身上设置适当的数据,但是最后对 pickingShipped() 的调用呢?这似乎使测试更加复杂。那么代码应该重新排列吗?如果是这样,怎么做?或者,这是我在第二个选项中概述的模拟的常见用例吗?如果是这样,像我展示的那样注入依赖项是否正确?
【问题讨论】:
标签: php laravel unit-testing phpunit