Laravel中具有模型和phpunit的奇怪行为-试图获取非对象的属性'id'

时间:2018-11-20 18:55:24

标签: laravel eloquent phpunit

我在laravel中使用PHPUnit有一些非常奇怪的行为。我有一个测试invoices_are_split_between_extensions,它会创建一些带有条目的时间表以及具有特殊条件的合同,需要进行测试。

我将所需的功能汇总为一个可以运行测试的功能为例。

/** @test */
public function invoices_are_split_between_extensions()
{
    $user = $this->user();
    $contract = factory(Contract::class)->states('complete')->create([
        'user_id' => $user->id
    ]);
    $extension = factory(ContractExtension::class)->create([
        'contract_id' => $contract->id,
        'start' => '2018-01-01',
        'end' => '2018-01-15',
        'sp' => '50',
        'pp' => '40',
    ]);
    $extension2 = factory(ContractExtension::class)->create([
        'contract_id' => $contract->id,
        'start' => '2018-01-16',
        'end' => '2018-01-31',
        'sp' => '50',
        'pp' => '40',
    ]);
    $timesheet = factory(Timesheet::class)->create([
        'user_id' => $user->id,
        'customer_id' => $contract->customer_id,
        'contract_id' => $contract->id,
        'extension_id' => $extension->id,
        'total' => 16,
        'date' => '2018-01-01',
    ]);
    $entry = factory(TimesheetEntry::class)->create([
        'date' => '2018-01-14',
        'value' => 8,
        'user_id' => $user->id,
        'tariff_id' => 1,
        'contract_id' => $contract->id,
        'customer_id' => $contract->customer_id,
        'extension_id' => $extension->id,
        'timesheet_id' => $timesheet->id,
        'invoiced' => false,
    ]);
    $entry1 = factory(TimesheetEntry::class)->create([
        'date' => '2018-01-15',
        'value' => 8,
        'user_id' => $user->id,
        'tariff_id' => 1,
        'contract_id' => $contract->id,
        'customer_id' => $contract->customer_id,
        'extension_id' => $extension->id,
        'timesheet_id' => $timesheet->id,
        'invoiced' => false,
    ]);
    $entry2 = factory(TimesheetEntry::class)->create([
        'date' => '2018-01-16',
        'value' => 4,
        'user_id' => $user->id,
        'tariff_id' => 1,
        'contract_id' => $contract->id,
        'customer_id' => $contract->customer_id,
        'extension_id' => $extension2->id,
        'timesheet_id' => $timesheet->id,
        'invoiced' => false,
    ]);

    $invoices = Invoice::fromTimesheet($timesheet);

    $this->assertCount(2, $invoices);
    $this->assertEquals(800, $invoices[0]->total);
    $this->assertEquals(200, $invoices[1]->total);
    $this->assertEquals($extension->id, $invoices[0]->extension_id);
    $this->assertEquals($extension2->id, $invoices[1]->extension_id);
}

此测试引发错误ErrorException: Trying to get property 'id' of non-object

1) Tests\Feature\InvoiceTest::invoices_are_split_between_extensions
ErrorException: Trying to get property 'id' of non-object

/home/ilyas/script/clockwork/contract-module/src/Models/Contract.php:435
/home/ilyas/script/clockwork/timesheet-module/src/Models/Timesheet.php:293
/home/ilyas/script/clockwork/app/src/vendor/laravel/framework/src/Illuminate/Support/Collection.php:1011
/home/ilyas/script/clockwork/app/src/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Collection.php:261
/home/ilyas/script/clockwork/timesheet-module/src/Models/Timesheet.php:303
/home/ilyas/script/clockwork/invoice-module/src/Models/Invoice.php:272
/home/ilyas/script/clockwork/app/src/tests/Feature/InvoiceTest.php:145

当我转到Contract.php中的第435行时,发现以下行。根据错误,$tariff->id不是对象。

$override = $this->tariffs->where('id', $tariff->id)->first()->pivot->sp ?? null;

在快速dd()之后,我发现这是一个对象,名为Tariff的{​​{1}}实例返回有效的雄辩对象。 现在,有趣的部分开始了。如果我得到Tariff::findOrFail($key);这样的ID,它就可以工作。如果我尝试使用类似$tariff['id']的方法,则会收到错误消息$tariff->toArray()

Error: Call to a member function toArray() on null

如果我在$tariff = $tariff->toArray(); $override = $this->tariffs->where('id', $tariff['id'])->first()->pivot->sp ?? null; 之前dd()美元关税,我将得到一份雄辩的款项。如果在toArray()之后dd(),我将得到与数组相同的集合。如果我移除$override,该错误会再次出现...这使我疯狂了几个小时。

我可以使用dd()轻松地修复该功能,但是我知道是什么导致了此问题。

0 个答案:

没有答案