如何在symfony中使用dataFixture和faker进行测试数据填充
我们将通过文章和对应的评论进行举例说明;文章和评论的对应关系是一对多。
请先自行创建Article和Comment的Entity类
安装doctrine-fixtures-bundle
1 | composer require --dev doctrine/doctrine-fixtures-bundle or composer req --dev orm-fixtures |
生成fixture
1 | php bin/console make:fixture |
或者手动创建fixture类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace App\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
class ArticleFixtures extends Fixture
{
public function load(ObjectManager $manager)
{
// $product = new Product();
// $manager->persist($product);
$manager->flush();
}
}
编写ArticleFixtures 并生成第一篇文章
1 | public function load(ObjectManager $manager) |
然后 运行 生成第一篇文章1
php bin/console doctrine:fixtures:load
该命令会清空数据库 然后加载新数据 ,切记不能在线上数据库上使用 哈哈
接下来 让我们创建多篇文章
- 通过在load方法中使用
for循环进行处理 - 更棒的方式 通过创建一个BaseFixtures类 处理通用的多个entity保存
让我们创建BaseFixture类1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<?php
namespace App\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
abstract class BaseFixture extends Fixture
{
private $manager;
public function load(ObjectManager $manager)
{
$this->manager = $manager;
$this->loadData($manager);
}
/**
* 加载数据
*/
abstract protected function loadData(ObjectManager $manager);
}
修改ArticleFixtures 继承 BaseFixture
现在 在ArticleFixtures中不用处理load方法, 而是处理loadData方法
去除load,新增loadData
在BaseFixture中添加createManager方法
1 | protected function createMany(string $className, int $count, callable $factory) |
修改ArticleFixtures类中的loadData方法
1 | public function loadData(ObjectManager $manager) |
现在 重新加载数据
1 | php bin/console doctrine:fixtures:load |
yes it is success
使用Faker进行数据填充
安装faker
1 | composer require fzaninotto/faker --dev |
BaseFixture中使用faker
1 | + use Faker\Factory; |
数据填充
打开ArticleFixtures。我们已经在publishedAt上有一点随机性了。但是,Faker甚至可以在这里提供帮助:
如果$this->faker->boolean()第一个参数是获得的机会,true则将其更改为。
让我们使用70:每篇文章发表的几率为70%。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26private static $articleTitles = [
'Why Asteroids Taste Like Bacon',
'Life on Planet Mercury: Tan, Relaxing and Fabulous',
'Light Speed Travel: Fountain of Youth or Fallacy',
];
private static $articleContents = [
'Why Asteroids Taste Like Bacon',
'Life on Planet Mercury: Tan, Relaxing and Fabulous',
'Light Speed Travel: Fountain of Youth or Fallacy',
];
public function loadData(ObjectManager $manager)
{
$this->createMany(Article::class, 10, function(Article $article, $count) {
$article->setTitle($this->faker->randomElement(self::$articleTitles));
$article->setSlug($this->faker->slug);
$article->setContent($this->faker->randomElement(self::$articleContents));
if ($this->faker->boolean(70)) {
$article->setPublishedAt($this->faker->dateTimeBetween('-100 days', '-1 days'));
}
# $article->setHeartCount($this->faker->numberBetween(5, 100))
});
$manager->flush();
}
运行
1 | php bin/console doctrine:fixtures:load |
yes it is success
处理关联
创建CommentFixtures
1 | php bin/console make:fixtures |
使用通用的随机关联
1 | abstract class BaseFixture extends Fixture |
CommentFixtures中的修改
1 | #$comment->setArticle($this->getReference(Article::class.'_'.$this->faker->numberBetween(0, 9))); |
yes it is success ~ ~ ~
最后 fixtures类的执行顺序问题
默认情况下,它按字母顺序加载它们。所以 如果有关联模型的 一定 要定义依赖性来调整执行顺序
CommentFixtures的执行 需要先有ArticleFixtures
1 | # CommentFixtures.php |
that’s all ~~~~