You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: testing.md
+89-67Lines changed: 89 additions & 67 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -198,93 +198,115 @@ Another option is to wrap every test case in a database transaction. Again, Lume
198
198
<aname="model-factories"></a>
199
199
### Model Factories
200
200
201
-
When testing, it is common to need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Lumen allows you to define a default set of attributes for each of your [Eloquent models](https://laravel.com/docs/eloquent) using "factories". To get started, take a look at the `database/factories/ModelFactory.php` file in your application. Out of the box, this file contains one factory definition:
201
+
When testing, it is common to need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Lumen allows you to define a default set of attributes for each of your [Eloquent models](https://laravel.com/docs/eloquent) using model factories.
202
202
203
-
$factory->define('App\User', function ($faker) {
204
-
return [
205
-
'name' => $faker->name,
206
-
'email' => $faker->email,
207
-
];
208
-
});
203
+
To get started, take a look at the `database/factories/UserFactory.php` file in your application. Out of the box, this file contains the following factory definition:
209
204
210
-
Within the Closure, which serves as the factory definition, you may return the default test values of all attributes on the model. The Closure will receive an instance of the [Faker](https://github.com/fzaninotto/Faker) PHP library, which allows you to conveniently generate various kinds of random data for testing.
211
-
212
-
Of course, you are free to add your own additional factories to the `ModelFactory.php` file.
213
-
214
-
#### Multiple Factory Types
215
-
216
-
Sometimes you may wish to have multiple factories for the same Eloquent model class. For example, perhaps you would like to have a factory for "Administrator" users in addition to normal users. You may define these factories using the `defineAs` method:
217
-
218
-
$factory->defineAs('App\User', 'admin', function ($faker) {
219
-
return [
220
-
'name' => $faker->name,
221
-
'email' => $faker->email,
222
-
'admin' => true,
223
-
];
224
-
});
225
-
226
-
Instead of duplicating all of the attributes from your base user factory, you may use the `raw` method to retrieve the base attributes. Once you have the attributes, simply supplement them with any additional values you require:
205
+
<?php
206
+
207
+
namespace Database\Factories;
208
+
209
+
use App\Models\User;
210
+
use Illuminate\Database\Eloquent\Factories\Factory;
211
+
212
+
class UserFactory extends Factory
213
+
{
214
+
/**
215
+
* The name of the factory's corresponding model.
216
+
*
217
+
* @var string
218
+
*/
219
+
protected $model = User::class;
220
+
221
+
/**
222
+
* Define the model's default state.
223
+
*
224
+
* @return array
225
+
*/
226
+
public function definition()
227
+
{
228
+
return [
229
+
'name' => $this->faker->name,
230
+
'email' => $this->faker->unique()->safeEmail,
231
+
];
232
+
}
233
+
}
227
234
228
-
$factory->defineAs('App\User', 'admin', function ($faker) use ($factory) {
229
-
$user = $factory->raw('App\User');
235
+
As you can see, in their most basic form, factories are classes that extend Lumen's base factory class and define a `model` property and `definition` method. The `definition` method returns the default set of attribute values that should be applied when creating a model using the factory.
230
236
231
-
return array_merge($user, ['admin' => true]);
232
-
});
237
+
Via the `faker` property, factories have access to the [Faker](https://github.com/fzaninotto/Faker) PHP library, which allows you to conveniently generate various kinds of random data for testing.
233
238
234
-
#### Using Factories In Tests
239
+
#### Factory States
235
240
236
-
Once you have defined your factories, you may use them in your tests or database seed files to generate model instances using the global `factory` function. So, let's take a look at a few examples of creating models. First, we'll use the `make` method, which creates models but does not save them to the database:
241
+
State manipulation methods allow you to define discrete modifications that can be applied to your model factories in any combination. For example, your `User` model might have a `suspended` state that modifies one of its default attribute values. You may define your state transformations using the base factory's `state` method. You may name your state method anything you like. After all, it's just a typical PHP method:
If you would like to override some of the default values of your models, you may pass an array of values to the `make` method. Only the specified values will be replaced while the rest of the values remain set to their default values as specified by the factory:
255
+
If your state transformation requires access to the other attributes defined by the factory, you may pass a callback to the `state` method. The callback will receive the array of raw attributes defined for the factory:
246
256
247
-
$user = factory('App\User')->make([
248
-
'name' => 'Abigail',
249
-
]);
250
-
251
-
You may also create a Collection of many models or create models of a given type:
Factory callbacks are registered using the `afterMaking` and `afterCreating` methods and allow you to perform additional tasks after making or creating a model. You should register these callbacks by defining a `configure` method on the factory class. This method will automatically be called by Laravel when the factory is instantiated:
261
274
262
-
#### Persisting Factory Models
275
+
namespace Database\Factories;
263
276
264
-
The `create` method not only creates the model instances, but also saves them to the database using Eloquent's `save` method:
277
+
use App\Models\User;
278
+
use Illuminate\Database\Eloquent\Factories\Factory;
279
+
use Illuminate\Support\Str;
265
280
266
-
public function testDatabase()
281
+
class UserFactory extends Factory
267
282
{
268
-
$user = factory('App\User')->create();
269
-
270
-
// Use model in tests...
283
+
/**
284
+
* The name of the factory's corresponding model.
285
+
*
286
+
* @var string
287
+
*/
288
+
protected $model = User::class;
289
+
290
+
/**
291
+
* Configure the model factory.
292
+
*
293
+
* @return $this
294
+
*/
295
+
public function configure()
296
+
{
297
+
return $this->afterMaking(function (User $user) {
298
+
//
299
+
})->afterCreating(function (User $user) {
300
+
//
301
+
});
302
+
}
303
+
304
+
// ...
271
305
}
272
306
273
-
Again, you may override attributes on the model by passing an array to the `create` method:
274
-
275
-
$user = factory('App\User')->create([
276
-
'name' => 'Abigail',
277
-
]);
278
-
279
-
#### Adding Relations To Models
280
-
281
-
You may even persist multiple models to the database. In this example, we'll even attach a relation to the created models. When using the `create` method to create multiple models, an Eloquent [collection instance](http://laravel.com/docs/eloquent-collections) is returned, allowing you to use any of the convenient functions provided by the collection, such as `each`:
307
+
#### Using Factories In Tests
282
308
283
-
$users = factory('App\User', 3)
284
-
->create()
285
-
->each(function($u) {
286
-
$u->posts()->save(factory('App\Post')->make());
287
-
});
309
+
The Lumen model factories based on the same code as the Laravel model factories. Therefore, please consult the [full Laravel documentation](https://laravel.com/docs/8.x/database-testing#using-factories) for usage examples.
0 commit comments