测试 oneToMany 关系 Laravel、Eloquent 不起作用

Testing oneToMany relationship Laravel, Eloquent doesn't work

我无法理解这个:

$fragment = factory(Fragment::class)->create();

$this->assertCount(0, $fragment->values);

fragment->fetch(); // updates the 'values' by adding one Value object.

var_dump($fragment->id); // i.e. 6
var_dump(Fragment::first()->id); // 6 

var_dump($fragment->values->count());  // 0
var_dump(Fragment::first()->values->count()); // 1

$this->assertCount(1, $fragment->values);

我使用的是DatabaseTranscations,所以创建一个Fragment后,总是只有一个。因此,$fragment 和 Fragment::first() 是完全相同的实例。然而……价值关系是不同的。怎么会这样呢?

请注意,这仅在测试期间发生,当我通过我的控制器手动测试它时(并将值传递到 blade 模板页面)它工作正常。我很困惑:S。

有什么想法吗?

关系属性($fragment->values)只加载一次。当您从关系中添加或删除项目时,它们不会保持最新。他们不会每次都访问数据库来检查更改。

你的第二行是$this->assertCount(0, $fragment->values);。在这里访问 $fragment->values 延迟加载关系,正如你的断言所证明的那样,它是空的。

然后您调用 $fragment->fetch(),其中您的评论说它向片段添加了一个 Value 对象。但是,您的关系属性 ($fragment->values) 已经从之前的语句中加载,因此它不会反映您添加到关系中的额外 Value 对象。

因此,即使在调用 fetch() 之后,$fragment->values 仍然是一个空集合。 Fragment::first()->values 将包含新相关的 Value,因为它正在获取 Fragment 的新实例,并且当它第一次加载 values 时,它会选择上传相关 Value.

当需要重新加载关系时,可以使用load()方法。如果您在调用 fetch() 之后添加它(或将它放在您的 fetch() 方法中,以对您有意义的为准),您的测试将正常工作。

$fragment = factory(Fragment::class)->create();

$this->assertCount(0, $fragment->values);

$fragment->fetch(); // updates the 'values' by adding one Value object.

var_dump($fragment->id); // i.e. 6
var_dump(Fragment::first()->id); // 6 

var_dump($fragment->values->count());  // 0

// reload the values relationship
$fragment->load('values');

var_dump($fragment->values->count());  // 1
var_dump(Fragment::first()->values->count()); // 1

$this->assertCount(1, $fragment->values);

您的另一个选择是通过访问关系方法而不是关系属性来使用关系查询。如果您执行 $fragment->values()->count()(注意:values(),而不是 values),那么每次都会访问数据库并且总是 return 当前计数。