[Lumen5.2 document] more features-unit test-php Tutorial

Source: Internet
Author: User
Tags stream api
[Lumen5.2 documentation] more features-Unit testing 1. Introduction

Lumen is rooted in testing. In fact, using PHPUnit to provide test support is out-of-the-box, and the test configuration file phpunit. xml has been set for the application. The framework also provides many helper functions that allow you to perform more expressive tests on your applications.

The tests directory provides an ExampleTest. php file. after installing the new Lumen application, you can simply run phpunit on the command line to run the test.

1.1 Test Environment

During the test, Lumen automatically configures the cache driver as an array driver, which means that the cached data is not stored persistently during the test.

You can create other test environment configurations as needed. Testing Environment variables can be configured in the phpunit. xml file.

1.2 define and run the test

To create a test case, you just need to create a new test file in the tests Directory. The Test class should inherit TestCase, and then you can use PHPUnit to define the test method. To run the test, simply run the phpunit command from the terminal:

 assertTrue(true);    }}

Note: If you define your own setUp method in the Test class, make sure to call parent: setUp.

2. Application Testing

Lumen provides a stream API (method chain) for generating HTTP requests and test output ).

2.1 Test JSON API

Lumen also provides multiple auxiliary functions for testing JSON APIs and their responses. For example, the get, post, put, patch, and delete methods are used to send requests through multiple HTTP request methods. You can also easily pass data and headers to these methods. At the beginning, we wrote a test to generate a POST request to/user and asserted whether the returned data is in JSON format:

 Post ('/user', ['name' => 'Sally'])-> seeJson (['created '=> true,]);}

The seeJson method converts a given array to JSON, and then verifies the JSON fragments in the entire JSON response returned by the application. Therefore, if there are other attributes in the JSON response, the test will still pass as long as the given segment exists.

Exact JSON matching verification

If you want to verify the exact match between the given array and the JSON returned by the application, use the seeJsonEquals method:

 Post ('/user', ['name' => 'Sally'])-> seeJsonEquals (['created '=> true,]);}
2.2 Certification

The auxiliary function actingAs provides a simple implementation to authenticate a given user for the current user:

 create();        $this->actingAs($user)             ->get('/user')    }}
2.3 Custom HTTP requests

If you want to generate a custom HTTP request in the application and obtain the complete Illuminate \ Http \ Response object, you can use the call method:

public function testApplication(){    $response = $this->call('GET', '/');    $this->assertEquals(200, $response->status());}

If you want to generate a POST, PUT, or PATCH Request, you can input an array of input data in the Request. in the routing or controller, you can access the Request data through the Request instance:

$response = $this->call('POST', '/user', ['name' => 'Taylor']);
3. process the database

Lumen also provides a variety of useful tools to make testing database-driven applications easier. First, you can use the help function seeInDatabase to determine whether the data in the database matches the given data set. For example, if you want to go to the data table users to query whether the record exists through the condition where the email value is sally@example.com, we can do this:

Public function testDatabase () {// call the application... $ this-> seeInDatabase ('users', ['email '=> 'Sally @ foo.com']);}

Of course, the seeInDatabase method and other similar help functions are for convenience. you can also use all built-in assert functions of PHPUnit to supplement the test.

3.1 reset the database after each test

It is usually useful to reset the database after each test, so that the data in the last Test will not affect the next Test.

Use migration

One way is to roll back the database after each test and re-migrate it before the next Test. Lumen provides a simple DatabaseMigrationstrait for automatic processing. In the Test class, the trait is simply used as follows:

 get('/foo');    }}

Use transactions

Another way is to wrap each test case into a database transaction, and Lumen provides convenient DatabaseTransactionstrait to automatically handle it for you:

 get('/foo');    }}
3.2 Model factory

During testing, new data is usually inserted into the database before the test is executed. When creating test data, Lumen allows you to use "factories" to define a default set of attribute values for each Eloquent model, rather than manually specifying values for each column. At the beginning, let's take a look at the atabase/factories/ModelFactory. php file, which contains a factory definition:

$factory->define(App\User::class, function ($faker) {    return [        'name' => $faker->name,        'email' => $faker->email,    ];});

In the closure, as the factory definition, we return the default test values for all attributes in the model. This closure receives the Faker instance of the PHP library, allowing you to easily generate multiple types of random data for the test.

Of course, you can add more factories to the ModelFactory. php file.

Multiple factory types

Sometimes you may want to generate multiple factories for the same Eloquent model class. for example, apart from being used outdoors, you may want to generate a factory for the "administrator" user, you can use the defineAs method to define these factories:

$factory->defineAs(App\User::class, 'admin', function ($faker) {    return [        'name' => $faker->name,        'email' => $faker->email,        'admin' => true,    ];});

You can use the raw method to obtain basic attributes without repeating all the attributes in the basic user factory. after obtaining these attributes, you only need to add the additional values you require:

$factory->defineAs(App\User::class, 'admin', function ($faker) use ($factory) {    $user = $factory->raw(App\User::class);    return array_merge($user, ['admin' => true]);});

Factory used during testing

After the factory is defined, you can use the global factory method in the test or database fill file to generate model instances. Therefore, let's take a look at some examples of model generation. first, we use the make method to create a model without saving it to the database:

Public function testDatabase () {$ user = factory (App \ User: class)-> make (); // user model test ...}

If you want to override some default values of the model, you can pass the array value to the make method. Only the specified value is replaced, and other data remains unchanged:

$user = factory(App\User::class)->make([    'name' => 'Abigail',]);

You can also create multiple model sets or create a set of the given type:

// Create 3 App \ User instances... $ users = factory (App \ User: class, 3)-> make (); // create an App \ User "admin" instance... $ user = factory (App \ User: class, 'admin')-> make (); // create 3 App \ User "admin" instances... $ users = factory (App \ User: class, 'admin', 3)-> make ();

Persistent factory model

The create method not only creates model instances, but also saves them to the database using the save method of Eloquent:

Public function testDatabase () {$ user = factory (App \ User: class)-> create (); // user model test ...}

You can still overwrite the attributes of the model by passing an array to the create method:

$user = factory(App\User::class)->create([    'name' => 'Abigail',]);

Add Association relation model

You can even persist multiple models to the database. In this example, we add a model associated with the created model. when multiple models are created using the create method, an Eloquent collection instance is returned, this allows you to use all the convenient methods provided by the collection, such as each:

$users = factory(App\User::class, 3)           ->create()           ->each(function($u) {                $u->posts()->save(factory(App\Post::class)->make());            });
4. simulation4.1 simulate an event

If you are using Lumen-intensive event systems, you may want to simulate specific events during testing. For example, if you register a test user, you may not want all the time processors of UserRegistered to be triggered, because this may send a welcome email, and so on.

Lumen provides a convenient expectsEvents method to verify that the expected event is triggered, but it also prevents other processors from running the event:

 ExpectsEvents (App \ Events \ UserRegistered: class); // test the user registration code ...}}

If you want to prevent all events from running, you can use the withoutEvents method:

 WithoutEvents (); // test the user registration code ...}}
4.2 simulate a queue task

Sometimes, you may want to simply test the specified task distributed by the controller during the request, which allows you to isolate the test route/controller-to separate it from the task logic. of course, next, you can test the task itself in an independent test class.

Lumen provides a convenient expectsJobs method to verify that the expected task is distributed, but the task itself is not tested:

 ExpectsJobs (App \ Jobs \ PurchasePodcast: class); // Test and purchase the podcast code ...}}

Note: this method only checks the tasks that call $ this-> dispatch distribution through the global auxiliary function dispatch or the route/controller, and does not check the tasks that are directly distributed through Queue: push.

4.3 simulate a facade

During the test, you may often want to simulate the call of the Lumen facade, for example, look at the following controller action:

     

We can use the shouldReceive method to simulate the call of the Cache facade. this method returns a Mockery simulated instance. because the facade is parsed and managed through the Lumen service container, they are more testable than common static classes. For example, we can simulate the call of the Cache facade:

  once()                    ->with('key')                    ->andReturn('value');        $this->visit('/users');    }}

Note: do not simulate the Request facade. Instead, pass the input to the HTTP auxiliary functions such as call and post during the test.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.