[ Lumen 5.2 文档 ] 更多特性 -- 单元测试
1、简介
Lumen植根于测试,实际上,使用 PHPUnit对测试提供支持是开箱即用的,并且测试配置文件 phpunit.xml已经为应用设置好了。框架还提供了很多辅助函数从而允许你对应用进行更加富有表现力的测试。
tests目录中提供了一个 ExampleTest.php文件,安装完新的Lumen应用后,只需简单在命令行运行 phpunit即可运行测试。
1.1 测试环境
Lumen在测试时自动配置缓存驱动为数组驱动,这意味着测试时不会持久化存储缓存数据。
如果需要的话你可以自由创建其它测试环境配置。 testing环境变量可以在 phpunit.xml文件中配置。
1.2 定义&运行测试
要创建一个测试用例,只需简单在 tests目录创建一个新的测试文件,测试类应该继承 TestCase,然后你可以使用PHPUnit定义测试方法。要运行测试,简单从终端执行 phpunit命令即可:
<?phpclass FooTest extends TestCase{ public function testSomethingIsTrue() { $this->assertTrue(true); }}
注意:如果你在测试类中定义自己的 setUp方法,确保在其中调用 parent::setUp。
2、应用测试
Lumen为生成HTTP请求、测试输出提供了流接口API(方法链)。
2.1 测试 JSON API
Lumen还提供多个辅助函数用于测试JSON API及其响应。例如, get, post, put, patch, 和 delete方法用于通过多种HTTP请求方式发出请求。你还可以轻松传递数据和头到这些方法。作为开始,我们编写测试来生成POST请求到 /user并断言返回的数据是否是JSON格式:
<?phpclass ExampleTest extends TestCase{ /** * 基本功能测试示例 * * @return void */ public function testBasicExample() { $this->post('/user', ['name' => 'Sally']) ->seeJson([ 'created' => true, ]); }}
seeJson方法将给定数组转化为JSON,然后验证应用返回的整个JSON响应中的JSON片段。因此,如果在JSON响应中有其他属性,只要给定片段存在的话测试依然会通过。
精确验证JSON匹配
如果你想要验证给定数组和应用返回的JSON能够精确匹配,使用 seeJsonEquals方法:
<?phpclass ExampleTest extends TestCase{ /** * 基本功能测试示例 * * @return void */ public function testBasicExample() { $this->post('/user', ['name' => 'Sally']) ->seeJsonEquals([ 'created' => true, ]); }}
2.2认证
辅助函数 actingAs提供了认证给定用户为当前用户的简单实现:
<?phpclass ExampleTest extends TestCase{ public function testApplication() { $user = factory('App\User')->create(); $this->actingAs($user) ->get('/user') }}
2.3 自定义HTTP请求
如果你想要在应用中生成自定义HTTP请求并获取完整的 Illuminate\Http\Response对象,可以使用 call方法:
public function testApplication(){ $response = $this->call('GET', '/'); $this->assertEquals(200, $response->status());}
如果你要生成 POST, PUT, 或者 PATCH请求可以在请求中传入输入数据数组,在路由或控制器中可以通过Request实例访问请求数据:
$response = $this->call('POST', '/user', ['name' => 'Taylor']);
3、处理数据库
Lumen还提供了多种有用的工具让测试数据库驱动的应用更加简单。首先,你可以使用帮助函数 seeInDatabase来断言数据库中的数据是否和给定数据集合匹配。例如,如果你想要通过email值为 sally@example.com的条件去数据表 users查询是否存在该记录 ,我们可以这样做:
public function testDatabase(){ // 调用应用... $this->seeInDatabase('users', ['email' => 'sally@foo.com']);}
当然, seeInDatabase方法和其他类似帮助函数都是为了方便,你还可以使用所有PHPUnit内置的断言函数来补充测试。
3.1 每次测试后重置数据库
每次测试后重置数据库通常很有用,这样的话上次测试的数据不会影响下一次测试。
使用迁移
一种方式是每次测试后回滚数据库并在下次测试前重新迁移。Lumen提供了一个简单的 DatabaseMigrationstrait来自动为你处理。在测试类上简单使用该trait如下:
<?phpuse Laravel\Lumen\Testing\DatabaseMigrations;use Laravel\Lumen\Testing\DatabaseTransactions;class ExampleTest extends TestCase{ use DatabaseMigrations; /** * A basic functional test example. * * @return void */ public function testBasicExample() { $this->get('/foo'); }}
使用事务
另一种方式是将每一个测试用例包裹到一个数据库事务中,Lumen提供了方便的 DatabaseTransactionstrait自动为你处理:
<?phpuse Laravel\Lumen\Testing\DatabaseMigrations;use Laravel\Lumen\Testing\DatabaseTransactions;class ExampleTest extends TestCase{ use DatabaseTransactions; /** * A basic functional test example. * * @return void */ public function testBasicExample() { $this->get('/foo'); }}
3.2 模型工厂
测试时,通常需要在执行测试前插入新数据到数据库。在创建测试数据时,Lumen允许你使用”factories”为每个Eloquent模型定义默认的属性值集合,而不用手动为每一列指定值。作为开始,我们看一下 atabase/factories/ModelFactory.php文件,该文件包含了一个工厂定义:
$factory->define(App\User::class, function ($faker) { return [ 'name' => $faker->name, 'email' => $faker->email, ];});
在闭包中,作为工厂定义,我们返回该模型上所有属性默认测试值。该闭包接收PHP库 Faker实例,从而允许你方便地为测试生成多种类型的随机数据。
当然,你可以添加更多工厂到 ModelFactory.php文件。
多个工厂类型
有时候你可能想要为同一个Eloquent模型类生成多个工厂,例如,除了正常用户外可能你想要为“管理员”用户生成一个工厂,你可以使用 defineAs方法定义这些工厂:
$factory->defineAs(App\User::class, 'admin', function ($faker) { return [ 'name' => $faker->name, 'email' => $faker->email, 'admin' => true, ];});
你可以使用 raw方法获取基本属性而不用重复基本用户工厂中的所有属性,获取这些属性后,只需将你要求的额外值增补进去即可:
$factory->defineAs(App\User::class, 'admin', function ($faker) use ($factory) { $user = $factory->raw(App\User::class); return array_merge($user, ['admin' => true]);});
测试中使用工厂
定义好工厂后,可以在测试或数据库填充文件中通过全局的 factory方法使用它们来生成模型实例,所以,让我们看一些生成模型的例子,首先,我们使用 make方法,该方法创建模型但不将其保存到数据库:
public function testDatabase(){ $user = factory(App\User::class)->make(); // 用户模型测试...}
如果你想要覆盖模型的一些默认值,可以传递数组值到 make方法。只有指定值被替换,其他数据保持不变:
$user = factory(App\User::class)->make([ 'name' => 'Abigail',]);
还可以创建多个模型集合或者创建给定类型的集合:
// 创建3个 App\User 实例...$users = factory(App\User::class, 3)->make();// 创建1个 App\User "admin" 实例...$user = factory(App\User::class, 'admin')->make();// 创建3个 App\User "admin" 实例...$users = factory(App\User::class, 'admin', 3)->make();
持久化工厂模型
create方法不仅能创建模型实例,还可以使用Eloquent的 save方法将它们保存到数据库:
public function testDatabase(){ $user = factory(App\User::class)->create(); //用户模型测试...}
你仍然可以通过传递数组到create方法覆盖模型上的属性:
$user = factory(App\User::class)->create([ 'name' => 'Abigail',]);
添加关联关系到模型
你甚至可以持久化多个模型到数据库。在本例中,我们添加一个关联到创建的模型,使用 create方法创建多个模型的时候,会返回一个Eloquent集合实例,从而允许你使用集合提供的所有便利方法,例如 each:
$users = factory(App\User::class, 3) ->create() ->each(function($u) { $u->posts()->save(factory(App\Post::class)->make()); });
4、 模拟
4.1 模拟事件
如果你在重度使用Lumen的事件系统,可能想要在测试时模拟特定事件。例如,如果你在测试用户注册,你可能不想所有 UserRegistered的时间处理器都被触发,因为这可能会发送欢迎邮件,等等。
Lumen提供可一个方便的 expectsEvents方法来验证期望的事件被触发,但同时阻止该事件的其它处理器运行:
<?phpclass ExampleTest extends TestCase{ public function testUserRegistration() { $this->expectsEvents(App\Events\UserRegistered::class); // 测试用户注册代码... }}
如果你想要阻止所有事件运行,可以使用 withoutEvents方法:
<?phpclass ExampleTest extends TestCase{ public function testUserRegistration() { $this->withoutEvents(); // 测试用户注册代码... }}
4.2 模拟队列任务
有时候,你可能想要在请求时简单测试控制器分发的指定任务,这允许你孤立的测试路由/控制器——将其从任务逻辑中分离出去,当然,接下来你可以在一个独立测试类中测试任务本身。
Lumen提供了一个方便的 expectsJobs方法来验证期望的任务被分发,但该任务本身不会被测试:
<?phpclass ExampleTest extends TestCase{ public function testPurchasePodcast() { $this->expectsJobs(App\Jobs\PurchasePodcast::class); // 测试购买播客代码... }}
注意:这个方法只检查通过全局辅助函数dispatch或路由/控制器中调用$this->dispatch分发的任务,并不检查直接通过 Queue::push分发的任务。
4.3 模拟门面
测试的时候,你可能经常想要模拟Lumen门面的调用,例如,看看下面的控制器动作:
<?phpnamespace App\Http\Controllers;use Cache;use Illuminate\Routing\Controller;class UserController extends Controller{ /** * 显示应用用户列表 * * @return Response */ public function index() { $value = Cache::get('key'); // }}
我们可以通过使用 shouldReceive方法模拟 Cache门面的调用,该方法返回一个 Mockery模拟的实例,由于门面通过Lumen服务容器解析和管理,它们比通常的静态类更具有可测试性。例如,我们来模拟 Cache门面的调用:
<?phpclass FooTest extends TestCase{ public function testGetIndex() { Cache::shouldReceive('get') ->once() ->with('key') ->andReturn('value'); $this->visit('/users'); }}
注意:不要模拟 Request门面,取而代之地,在测试时传递输入到HTTP辅助函数如 call和 post。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Laravel은 직관적 인 플래시 방법을 사용하여 임시 세션 데이터 처리를 단순화합니다. 응용 프로그램에 간단한 메시지, 경고 또는 알림을 표시하는 데 적합합니다. 데이터는 기본적으로 후속 요청에만 지속됩니다. $ 요청-

PHP 클라이언트 URL (CURL) 확장자는 개발자를위한 강력한 도구이며 원격 서버 및 REST API와의 원활한 상호 작용을 가능하게합니다. PHP CURL은 존경받는 다중 프로모토콜 파일 전송 라이브러리 인 Libcurl을 활용하여 효율적인 execu를 용이하게합니다.

Alipay PHP ...

Laravel은 간결한 HTTP 응답 시뮬레이션 구문을 제공하여 HTTP 상호 작용 테스트를 단순화합니다. 이 접근법은 테스트 시뮬레이션을보다 직관적으로 만들면서 코드 중복성을 크게 줄입니다. 기본 구현은 다양한 응답 유형 단축키를 제공합니다. Illuminate \ support \ Facades \ http를 사용하십시오. http :: 가짜 ([ 'google.com'=> 'Hello World', 'github.com'=> [ 'foo'=> 'bar'], 'forge.laravel.com'=>

고객의 가장 긴급한 문제에 실시간 인스턴트 솔루션을 제공하고 싶습니까? 라이브 채팅을 통해 고객과 실시간 대화를 나누고 문제를 즉시 해결할 수 있습니다. 그것은 당신이 당신의 관습에 더 빠른 서비스를 제공 할 수 있도록합니다.

기사는 PHP 5.3에 도입 된 PHP의 LSB (Late STATIC BING)에 대해 논의하여 정적 방법의 런타임 해상도가보다 유연한 상속을 요구할 수있게한다. LSB의 실제 응용 프로그램 및 잠재적 성능

기사는 입력 유효성 검사, 인증 및 정기 업데이트를 포함한 취약점을 방지하기 위해 프레임 워크의 필수 보안 기능을 논의합니다.

JWT는 주로 신분증 인증 및 정보 교환을 위해 당사자간에 정보를 안전하게 전송하는 데 사용되는 JSON을 기반으로 한 개방형 표준입니다. 1. JWT는 헤더, 페이로드 및 서명의 세 부분으로 구성됩니다. 2. JWT의 작업 원칙에는 세 가지 단계가 포함됩니다. JWT 생성, JWT 확인 및 Parsing Payload. 3. PHP에서 인증에 JWT를 사용하면 JWT를 생성하고 확인할 수 있으며 사용자 역할 및 권한 정보가 고급 사용에 포함될 수 있습니다. 4. 일반적인 오류에는 서명 검증 실패, 토큰 만료 및 대형 페이로드가 포함됩니다. 디버깅 기술에는 디버깅 도구 및 로깅 사용이 포함됩니다. 5. 성능 최적화 및 모범 사례에는 적절한 시그니처 알고리즘 사용, 타당성 기간 설정 합리적,
