در حال بارگذاری ...

Introducing Model Factories0:00

Check this out, if I go to database, factories, and model factory, if we scroll down, you'll see some code here that either looks pretty darn familiar or completely foreign. In Laravel 5.1, we have a factory builder straight out of the box. So if you've ever been in those situations where you want to build up a number of any kind of data, in this case we have users, if you just wanted to say, well, quickly throw in 10 users into a database table, or maybe you even want database seeding, and you quickly want to populate a table with 100 users. Well, in the past, this was always sort of annoying, and you had to manually wrangle that together. Instead, we have a much better API, and if you've ever used something like the test dummy

that together. Instead, we have a much better API, and if you've ever used something like the test-dummy package for Laracast, well once again, a lot of those ideas are now part of Laravel 5.1. Here's how it works. We are going to define a new factory. You give it the name of the class. This is the same thing, by the way, as saying App\User. But with PHP 5.5, you could always say App\User::class to achieve the same end result, but the advantage is obviously this is a lot more friendly for IDEs. I can click right through to the User when you kind of can't do that in some editors.

Defining Factory Blueprints1:10

but the advantage is obviously this is a lot more friendly for IDEs. I can click right through to the User when you kind of can't do that in some editors if it's just a string. Okay, so next, we have, think of this as the makeup or the blueprint for what a User would look like. A User has a name, email, password, and also a rememberToken. But we don't really just want to manually do this stuff, JohnDoe and stuff like that. Yeah, you could, but it's a little time consuming, and ideally, it would be nice if this was all random through each iteration, in fact. So that's where the Faker library comes into play.

all random through each iteration, in fact. So that's where the Faker library comes into play. This gives us a really simple way to build up dummy data for basically anything you would need. For example, you want a name, that'll give you a random name, or a random email, or an address, or tons of different things. You can refer to the Faker documentation for a massive list of hundreds of options. But most of the time, you'll even be able to guess what the property name is. So now, how does this all work? We have this factory, but how do we make use of it?

Generating Models in Tinker2:12

So now, how does this all work? We have this factory, but how do we make use of it? Well, let me show you. To begin, we'll do php artisan tinker. And one new helper function in Laravel 5.1 is simply factory. And this is sort of like a magic function, where it's pretty dynamic, at least in terms of the arguments that you pass to it. It'll figure out what you're trying to do. So for example, let's say I want a factory for a User, and I don't want to persist this to the database, I just want a User object.

So for example, let's say I want a factory for a User, and I don't want to persist this to the database, I just want a User object. I could say make. And there you go. We have a User with a name and email. And don't forget, we leave off password because, of course, that should be hidden. So that's intended behavior. But now if I run this again, notice how the name will be different every single time. We can thank the Faker library for that. But now, what if we want, how about, five different Users?

We can thank the Faker library for that. But now, what if we want, how about, five different User objects? You can pass that as the second argument here. There you go. Now we have a collection of User objects, and each one is unique. So cool. But now in this case, once again, we're not persisting it. We're just building up User objects and then collecting them. If we want to persist them, then we can use create. It does the same thing, but it saves them.

If we want to persist them, then we can use create. It does the same thing, but it saves them. So now if we run it, yes, you have your five records, but, well, let's see. I'm using SQLite here. SELECT * FROM users, and just like that, we have five records in the database. And real quick, notice that the password is in plain text. You would probably want to run that through bcrypt, of course. So now, as you can imagine, this can be hugely useful, not just for testing, but general database seeding. For example, let's go into database, seeds, and we'll put it right here.

Seeding the Database3:51

database seeding. For example, let's go into database/seeds, and we'll put it right here. We could call a custom class, or we could do it right here. Factory, App\User, class, and I want 50 users. Create them. And let's see. We want to truncate them too. So you know what? Let's export that, and then right here, we'll say User::truncate like this. And yeah, you could extract that to a method or a class that we call from here, whatever.

Let's export that, and then right here, we'll say user truncate like this. And yeah, you could extract that to a method or a class that we call from here, whatever you want. It's just an example. But now, to build up a User and save 50 iterations of that User to the database, this is all you have to do, a single line of code. So why don't we try this out? php artisan db:seed, and we're done. If we now bring back SQLite again and select start from users, we should now have 50 users in the table, and we do.

Using Factories in Tests4:39

If we now bring back SQLite again and select start from users, we should now have 50 users in the table, and we do. So yeah, I love that. Now, that's database seeding, but like I said, you can also use this for the purposes of testing. Traditionally, you use it for the purposes of testing. So what might that look like? Well, I, behind the scenes, I created a little migration for some posts. Just basic post table, nothing fancy. But now I want to say, well, how about given I have one or two posts in the database, when

Just basic post table, nothing fancy. But now I want to say, well, how about given I have one or two posts in the database, when I visit a post's URI, then I expect to see those, right? Basic stuff. Okay, how do we do that? Well, we know about this factory global function. So I could say at Post class, or if we're going to use this a lot, let's import it and then clean this up. And well, maybe we just need one post. So we could say create.

And well, maybe we just need one post. So we could say create. Okay, and we'll save that to post. But now this isn't going to work, right? And in fact, it's going to fail immediately. Let me show you. Yep, unable to locate a factory with that name. All right, well, that's because, of course, within ModelFactory, we have a definition, so to speak, for a User, but not for a Post. So let's create one.

so to speak, for a User, but not for a Post. So let's create one. You'll do this for every table that you want to make use of the factory with. So I will change this to Post. And like I said, a Post just has a title. Now this can just be, how about a sentence? And then the body of it, well, maybe we can make that a paragraph. Okay, so we have the makeup for a Post. If we were to come back, well, why don't we just dd the post, and you'll see it's already working.

If we were to come back, well, why don't we just die and dump the Post, and you'll see it's already working. phpunit, and there we go. We have our data that has been saved to the database. But now, real quick, let's just run it a bunch of times, and we're going to fall into this trap where now our database is full of stuff we don't want. select * from posts. These were for testing, if I zoom out, but now they're just going to be saved there. And by the way, right now we're just using the production database. In real life, in your phpunit.xml file, you would specify a test-specific database.

And by the way, right now we're just using the production database. In real life, in your phpunit.xml file, you would specify a test-specific database. But anyways, we don't want this. We want this to be reset after each test, and we talked about this at the end of the previous video. So let's delete from posts, and now this time we will use database transactions for all of these tests. And that way, we'll roll everything back on teardown. So now, if I open up a new tab and we run phpunit, no matter how many times we do this, we roll it back at the end.

So now, if I open up a new tab and we run phpunit, no matter how many times we do this, we roll it back at the end. So let's do another select * , and you'll see that's empty, which is what we want. Cool. So now, we just write our tests. This, when I visit posts, well, I expect to see, well, the title of the post. postTitle. Okay. We're not running gulp, so let's run phpunit, and it's going to fail, of course. In this case, we have a 404 because we have no endpoint yet.

Adding Posts Endpoint and View7:38

We're not running gulp, so let's run phpunit, and it's going to fail, of course. In this case, we have a 404 because we have no endpoint yet. So let's run pods.php, set up an endpoint, or don't forget, you can just use get if you want. Anyways, posts, and that's going to return to me a listing of all posts. Return view posts with posts equals Post::all(). Okay. Now, very quickly, we will filter through our posts. For each post as post, and then end for each. Then we'll have an article and display the title of the post as well as the body of the

For each post as post, and then end for each. Then we'll have an article and display the title of the post as well as the body of the post. All right. Let's run phpunit again, and hopefully, we'll get green. And we do. Okay. So that's model factories in a nutshell. It's pretty cool, and it's native to Laravel 5.1.

It's pretty cool, and it's native to Laravel 5.1.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟