Laravel-伪造单元测试中的保存失败

时间:2019-06-03 08:09:12

标签: laravel phpunit

如果我们有以下要测试的代码,那么模拟失败保存的最佳方法是什么?目前,我考试中唯一缺少的部分是else语句。

保存是循环的一部分,我们在其中进行$customers循环并执行一些操作。

$customers = Customer::where('created_at', '<=', $start);

$customers->each(function ($customer, $key) {
    if ($customer->save()) {
        //Do something here
    } else {
        //Saving failed, log something
    }
}

所有测试数据都来自工厂,并且每次测试都是即时生成的。

1 个答案:

答案 0 :(得分:0)

一件容易但肮脏的事情是通过saving事件伪造保存失败:

这是事件处理程序中的注释:

public function save(array $options = [])
{
    $query = $this->newModelQuery();

    // If the "saving" event returns false we'll bail out of the save and return
    // false, indicating that the save failed. This provides a chance for any
    // listeners to cancel save operations if validations fail or whatever.
    if ($this->fireModelEvent('saving') === false) {
        return false;
    }
   ....

因此,类似以下的内容应该起作用:

class TestModelSaving {
     public function testSaveFailureLogs() {
          // Create the fake model here
          // If the event handler for saving returns false then `save()` will return false
          Customer::saving(function () { return false; }); 
          // Call your unit under test here

          // Cleanup: Usually unnecessary, but some test configurations might need it
          Customer::flushEventListeners();

     }
}

为了测试是否记录了事件,您可以通过Log::shouldReceive(....)模拟记录器外观(具有相同名称的模拟函数的参数相同)