• Stars
    star
    461
  • Rank 95,028 (Top 2 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 10 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Easy factories for PHP integration testing.

TestDummy Build Status SensioLabsInsight

TestDummy makes the process of preparing factories (dummy data) for your integration tests as easy as possible. As easy as...

Build a Post model with dummy attributes.

use Laracasts\TestDummy\Factory;

$post = Factory::build('Post');

If we then do $post->toArray(), this might return:

array(4) {
  ["title"]=>
  string(21) "The Title of the Post"
  ["author_id"]=>
  string(1) "5"
  ["body"]=>
  string(226) "Iusto qui optio et iste. Cumque aliquid et omnis enim. Nesciunt ad esse a reiciendis expedita quidem veritatis. Nostrum repellendus reiciendis distinctio amet sapiente. Eum molestias a recusandae modi aut et adipisci corrupti."
  ["publish_date"]=>
  string(19) "2014-03-02 11:05:48"
}

Build a post, but override the default title.

use Laracasts\TestDummy\Factory;

$post = Factory::build('Post', ['title' => 'Override Title']);

Again, when cast to an array...

array(4) {
  ["title"]=>
  string(14) "Override Title"
  ["author_id"]=>
  string(1) "5"
  ["body"]=>
  string(254) "In eos porro qui est rerum possimus voluptatem non. Repudiandae eaque nostrum eaque aut deleniti possimus quod minus. Molestiae commodi odit sunt dignissimos corrupti repudiandae quibusdam quo. Autem maxime tenetur autem corporis aut quis sint occaecati."
  ["publish_date"]=>
  string(19) "2013-06-24 10:01:30"
}

Build an array of attributes for the model.

$post = Factory::attributesFor('Post');

The difference between build() and attributesFor() is that the former will return an instance of the given model type (such as Post). The latter will simply return an array of the generated attributes, which can be useful in some situations.

Build and persist a song entity.

use Laracasts\TestDummy\Factory;

$song = Factory::create('Song');

Create and persist a comment three times.

use Laracasts\TestDummy\Factory;

Factory::times(3)->create('Comment');

In effect, this will give you three rows in your comments table. If that table has relationships (such as an owning Post), those related rows will be created with dummy data as well.

Usage

Step 1: Install

Pull this package in through Composer, just like any other package.

"require-dev": {
    "laracasts/testdummy": "~2.0"
}

Step 2: Create a Factories File

TestDummy isn't magic. You need to describe the type of data that should be generated.

Within a tests/factories directory, you may create any number of PHP files that will automatically be loaded by TestDummy. Why don't you start with a generic tests/factories/factories.php file.

Each factory file you create will automatically have access to two variables:

  • $factory
  • $faker

$factory is the function that you'll use to define new sets of data, such as the makeup of a Post or Album.

$factory('Album', [
    'name' => 'Rock or Bust',
    'artist' => 'AC/DC'
]);

Think of this as your definition for any future generated albums - like when you do this:

use Laracasts\TestDummy\Factory;

$album = Factory::create('Album');

Faker

You probably won't want to hardcode strings for your various factories. It would be easier and faster to use random data. TestDummy pulls in the excellent Faker library to assist with this.

In fact, any files in your tests/factories/ directory will automatically have access to a $faker object that you may use. Here's an example:

$factory('Comment', [
    'body' => $faker->sentence
]);

Now, each time you generate a new comment, the body field will be set to a random sentence. Refer to the Faker documentation for a massive list of available fakes.

Relationships

If you wish, TestDummy can automatically generate your relationship models, as well. You just need to let TestDummy know the type of its associated model. TestDummy will then automatically build and save that relationship for you!

Using the Comment example from above, it stands to reason that a comment belongs to a user, right? Let's set that up:

$factory('Comment', [
    'user_id' => 'factory:User',
    'body' => $faker->sentence
]);

That's it! Notice the special syntax here: "factory:", followed by the name of the associated class/model.

To illustrate this with one more example, if a song belongs to an album, and an album belongs to an artist, then we can easily represent this:

$factory('App\Song', [
    'album_id' => 'factory:App\Album',
    'name' => $faker->sentence
]);

$factory('App\Album', [
    'artist_id' => 'factory:App\Artist',
    'name' => $faker->word
]);

$factory('App\Artist', [
    'name' => $faker->word
]);

So here's the cool thing: this will all work recursively. In translation, if you do...

use Laracasts\TestDummy\Factory;

$song = Factory::create('App\Song');

...then not only will TestDummy build and persist a song to the database, but it'll also do the same for the related album, and its related artist. Nifty!

Custom Factories

So far, you've learned how to generate data, using the name of the class, like App\User. However, sometimes, you'll want to define multiple types of users for the purposes of testing.

While it's true that you can use overrides, like this:

Factory::create('App\User', ['role' => 'admin']);

...if this is something that you'll be doing often, create a custom factory, like so:

// A generic factory for users...

$factory('App\User', [
    'username' => $faker->username,
    'password' => $faker->password,
    'role'     => 'member'
]);

// And a custom one for administrators

$factory('App\User', 'admin_user', [
    'username' => $faker->username,
    'password' => $faker->password,
    'role'     => 'admin'
]);

In the code snippet above, you're already familiar with the first example. For the second one, notice that we've added a "short name", or identifier for this special type of user factory. Now, whenever you want to quickly generate an admin user, you may do:

use Laracasts\TestDummy\Factory;

$adminUser = Factory::create('admin_user');

Defining with Closures

Alternatively, you may pass a closure as the second argument to the $factory method. This can be useful for situations where you need a bit more control over the values that you assign to each attribute. Here's an example:

$factory('App\Artist', function($faker) {
    $name = sprintf('Some Band Named %s', $faker->word);
    
    return [
        'name' => $name
    ];
});

Of course, just be sure to return an array from this closure. If you don't, an exception will be thrown.

Step 3: Setup

When testing against a database, it's recommended that each test works with the exact same database environment and structure. That way, you can protect yourself against false positives. An SQLite database (maybe even one in memory) is a good choice in these cases.

public function setUp()
{
    parent::setUp();

    Artisan::call('migrate');
}

Or, if a DB in memory isn't possible, to save a bit of time, a helper Laracasts\TestDummy\DbTestCase class is included with this package. If you extend it, before each test, your test DB will be migrated (if necessary), and all DB modifications will be channelled through a transaction, and then rolled back on tearDown. This will give you a speed boost, and ensure that all tests start with the same database structure.

use Laracasts\TestDummy\DbTestCase;

class ExampleTest extends DbTestCase {

    /** @test */
    function it_does_something()
    {
        // Before each test, your database will be rolled back
    }
}

Step 4: Write Your Tests

You're all set to go now. Start testing! Here's some code to get you started. Assuming that you have a Post and Comment model created...

use Laracasts\TestDummy\Factory;

$comment = Factory::create('Comment');

This will create and save both a Comment, as well as a Post record to the database.

Or, maybe you need to write a test to ensure that, if you have three songs with their respective lengths, when you call a getTotalLength method on the owning Album model, it will return the correct value. That's easy!

// create three songs, and explicitly set the length
Factory::times(3)->create('Song', ['length' => 200]);

$album = Album::first(); // this will be created once automatically.

$this->assertEquals(600, $album->getTotalLength());

Now, of course, just make sure that you've registered a definition for a Song and Album in one of your factory files, and you're good to go!

// tests/factories/factories.php

$factory('Song', [
  'album_id' => 'factory:Album',
  'name' => $faker->sentence
]);

$factory('Album', [
  'name' => $faker->sentence
]);

FAQ

How do I specify a different factories folder?

Easy. Before your tests run, add:

Factory::$factoriesPath = 'app/tests/factories';

Now, TestDummy will look for your registered factories in the app/tests/factories folder.

I want to control how my models are built and saved...

Okay, just create your own implementation of Laracasts\TestDummy\IsPersistable. This contract is composed of a few methods that you'll need to implement.

Once you have your implementation, before your tests run, add:

Factory::$databaseProvider = new MyCustomBuilder;

And that's it! Now, whenever you generate and save an entity, TestDummy will reference your custom implementation.

More Repositories

1

flash

Easy flash notifications
PHP
2,637
star
2

Laravel-5-Generators-Extended

This package extends the core file generators that are included with Laravel 5
PHP
2,447
star
3

PHP-Vars-To-Js-Transformer

Transform PHP data to JavaScript.
PHP
2,206
star
4

Lets-Build-a-Forum-in-Laravel

http://laracasts.com/series/lets-build-a-forum-with-laravel
JavaScript
912
star
5

Presenter

Easy view presenters in your apps.
PHP
864
star
6

cypress

Laravel Cypress Integration
PHP
568
star
7

Integrated

Simple, intuitive integration testing with PHPUnit.
PHP
478
star
8

Vue-Forms

https://laracasts.com/series/learn-vue-2-step-by-step/episodes/19
PHP
402
star
9

Commander

Easily leverage commands and domain events in your Laravel projects.
PHP
283
star
10

Behat-Laravel-Extension

Laravel extension for Behat functional testing.
PHP
261
star
11

matryoshka

Russian Doll Caching in Laravel
PHP
237
star
12

birdboard

Birdboard Series Code
PHP
236
star
13

Tweety

The final project from Laravel From Scratch.
PHP
178
star
14

The-PHP-Practitioner-Full-Source-Code

PHP
176
star
15

Laravel-From-Scratch-HTML-CSS

The HTML and CSS for the blog design for Laravel From Scratch
HTML
158
star
16

laravel-5-roles-and-permissions-demo

https://laracasts.com/series/whats-new-in-laravel-5-1/episodes/16
PHP
153
star
17

Validation

Easy form validation.
PHP
150
star
18

larabook

Larabook Series
PHP
142
star
19

PHP-For-Beginners-Series

PHP
119
star
20

laravel-vue-spa

PHP
110
star
21

Dedicated-Query-String-Filtering

https://laracasts.com/series/eloquent-techniques/episodes/4
PHP
94
star
22

Code-Katas-in-PHP

Screencasts of various code kata challenges in HP.
PHP
88
star
23

Email-Verification-In-Laravel

PHP
83
star
24

URL-Shortener

For demo at Laracasts.com
PHP
82
star
25

The-PHP-Practitioner-Episode-16

PHP
70
star
26

Eloquent-Outside-of-Laravel

In this lesson, you'll learn how to use Eloquent in a simple vanilla PHP environment. Luckily, it's pretty easy! For smaller projects that don't require the overhead of a full-stack framework, this method can be a great choice!
PHP
69
star
27

eloquent-performance-patterns

PHP
62
star
28

Build-An-Activity-Feed-in-Laravel

https://laracasts.com/lessons/build-an-activity-feed-in-laravel
JavaScript
58
star
29

Laravel-Redis-and-Socket.io

PHP
56
star
30

Laravel-OAuth-and-Socialite

PHP
55
star
31

Laravel-and-Vue

JavaScript
54
star
32

Email-Only-Authentication-With-Laravel

https://laracasts.com/series/laravel-authentication-techniques/episodes/1
PHP
54
star
33

transcriptions

Load and parse VTT files.
PHP
53
star
34

Laravel-and-Angular-Goodness

PHP
53
star
35

testingvue

http://testingvue.com
PHP
50
star
36

simple-di-container

PHP
48
star
37

Vue-SPA-Essentials-Routing

JavaScript
45
star
38

Mass-User-Settings

PHP
40
star
39

Users-and-Roles-in-Laravel

What if you want to assign a user to a particular role? For example, some of them might be classified as members, while others could be administrators. How might we allow for such things?
PHP
40
star
40

Nested-Comments

PHP
38
star
41

Gilded-Rose-Kata-in-PHP

PHP
38
star
42

Laravel-Elixir-Vueify-Setup

JavaScript
38
star
43

Blade-Component-Examples

PHP
37
star
44

In-Stock-Tracker

PHP
34
star
45

roles-and-abilities

PHP
33
star
46

socket-io-chat-example-app

HTML
32
star
47

Reports-and-Graphs

Using ChartJS to build line graphs with Laravel.
PHP
32
star
48

Accept-Payments-With-Stripe

https://laracasts.com/series/how-to-accept-payments-with-stripe
PHP
31
star
49

The-Vast-World-of-Vuejs

Lesson 1 Source
HTML
30
star
50

How-Do-I-Create-A-Star-Rating-System

https://laracasts.com/series/how-do-i/episodes/22
PHP
29
star
51

Learn-Flexbox-Through-Examples

HTML
29
star
52

JS-Component-Playground

https://laracasts.com/series/practical-vue-components
PHP
28
star
53

The-PHP-Practitioner-Episode-20

https://laracasts.com/series/php-for-beginners/episodes/20
PHP
27
star
54

GitHub-Authentication-With-Laravel

There are a number of excellent OAuth packages available, however, this is Laracasts, and we want to know how to, not reinvent the wheel, but rebuild the wheel! With that in mind, in this lesson, let's review the general process of how to allow your users to login to your application, using GitHub (or any provider).
PHP
26
star
55

build_a_forum_with_laravel_2023

Vue
24
star
56

Building-User-Profiles

In this lesson, we'll review the process of adding user profiles to an application. In the process, we'll review everything from database design, to migrations, to security, to validation. Let's get going!
PHP
24
star
57

laravel-api-master-class

PHP
24
star
58

Vue-and-Laravel-Workflow

JavaScript
24
star
59

Testing-Vue

JavaScript
23
star
60

Behat-Laravel-Extension-Example-App

Quick example app to demonstrate setting up Behat with Mink and Laravel extension
CSS
23
star
61

Pjax-and-Laravel

PHP
22
star
62

adding-passkeys-to-your-laravel-app

The repository for Luke's "Adding Passkeys to Your Laravel App" course.
PHP
21
star
63

Billing-With-Stripe

PHP
21
star
64

Build-Command-line-Apps

PHP
21
star
65

Widget

Simple view widgets.
PHP
20
star
66

todomvc-alpine

A quick TodoMVC implementation with Alpine.js
HTML
20
star
67

laravel-preset

The Laracasts default Laravel preset.
PHP
19
star
68

Russian-Doll-Caching-in-Laravel

https://laracasts.com/series/russian-doll-caching-in-laravel
PHP
19
star
69

Authentication-With-GitHub

https://laracasts.com/series/laravel-authentication-techniques/episodes/2
PHP
18
star
70

Pusher-Lesson

So you run a forum, and need some way to notify readers, if new replies have been left on a thread since their last page load. Well, how the heck do we do that? How do we say, "If a new reply is saved to the server, instantly update all viewers who might be reading the associated forum thread"? Well, Pusher can make these sorts of tasks a cinch! You'll love it.
JavaScript
18
star
71

Build-Artisan-Commands-With-TDD

In this fun two-part series, we'll use TDD to build a helpful Artisan command. Along the way, we'll leverage both Codeception (for the end-to-end tests) and PHPSpec (for unit tests) to drive our code. There's lots to learn, so let's get going.
PHP
18
star
72

PHP-Testing-Jargon

PHP
17
star
73

Document-Adjustments-Demo

https://laracasts.com/series/eloquent-techniques/episodes/3
PHP
17
star
74

form-objects-lesson

https://laracasts.com/series/whipping-monstrous-code-into-shape/episodes/1
PHP
17
star
75

Reusable-Repositories

So you're using repositories, but have found the process of constantly reimplementing common methods to be cumbersome?
PHP
17
star
76

Bash-Bootstraps

Often, it can prove helpful to write simple Bash scripts to bootstrap your new applications. The only question is…how do we do that? Let me show you!
Shell
17
star
77

VideoJS-Events-and-AJAX

PHP
16
star
78

Snippets-Project

https://laracasts.com/series/how-do-i/episodes/13
PHP
16
star
79

Transactional-Emails-in-Laravel-with-Campaign-Monitor

PHP
16
star
80

assets-website

PHP
15
star
81

Design-a-Fluent-API-with-TDD

https://laracasts.com/series/phpunit-testing-in-laravel/episodes/11
PHP
15
star
82

Help-Me-Understand-When-to-Use-Polymorphic-Relations

PHP
15
star
83

PHPSpec-Rocks

PHPSpec is the best test framework that you likely haven't used. That just might change after watching this video, though. It's excellent!
PHP
15
star
84

PHPSpec-Laravel-and-Refactoring

Any confusion that surrounds PHPSpec likely stems from a misunderstanding of what the framework is for. There are multiple styles and forms of testing; PHPSpec is not meant to fill all of those checkboxes. Let's talk about that in this lesson, while using BDD to build a class within a Laravel app.
PHP
14
star
85

Crazy-Simple-Pagination

PHP
13
star
86

Flexible-Flash-Messages

You'll frequently find yourself in the position of needing to notify your users, in response to some particular action. In this lesson, we'll uses tests to drive flexible flash messaging.
PHP
13
star
87

the-specification-pattern-in-php

PHP
13
star
88

laravel-workflow-for-swapping-vue-components

JavaScript
13
star
89

Bulk-Email-Notifications

In this lesson, we'll finish up our Mailchimp email notifications mini-project. Specifically, we'll focus on putting all the pieces that we built in the previous lesson together. This will include the creation of a UsersController, as well as a custom Artisan command to manually notify lesson subscribers.
PHP
13
star
90

Dynamic-Graphs-Lesson

https://laracasts.com/series/charting-and-you/episodes/8
JavaScript
13
star
91

Form-Validation-Simplified

Form validation is an interesting thing. It's trivial to implement, yet everyone tackles it differently. In this lesson, I'd like to show you my current approach (as of April, 2014) for handling this incredibly common task.
PHP
12
star
92

Laracasts-Docs

https://laracasts.com/series/how-to-read-code/episodes/6
PHP
12
star
93

How-Do-I-Dry-Up-My-Forms

PHP
12
star
94

Laravel-4.1-Password-Resets

PHP
12
star
95

Getting-Jiggy-With-Adapters

An adapter is one of the easier design patterns to learn. The reason why is because you use them in the real world all the time! In this lesson, let's review a handful of examples to figure out how it all works.
PHP
12
star
96

exploring-laravel-reverb

The source code for Luke's "Exploring Laravel Reverb" Larabit
PHP
12
star
97

6-html-tags

6 New'ish HTML Tags You Can Use Right Now
HTML
11
star
98

gilded-rose-with-phpunit

Original Kata and Description: https://github.com/notmyself/GildedRose
PHP
10
star
99

Hands-On-Community-Contributions

https://laracasts.com/series/hands-on-community-contributions/episodes/13
PHP
10
star
100

Small-Objects-Are-a-Good-Thing-and-Other-Refactoring-Lessons

How many times have you written (or come across) a controller method that's dozens of lines long. Surely, there are better ways to structure our code, right? Of course. In this lesson, let's learn about everything from security, to small objects, to events.
PHP
10
star