ホームページ  >  記事  >  バックエンド開発  >  Laravel チュートリアル: スタブを使用して単体テストの依存関係を解決する

Laravel チュートリアル: スタブを使用して単体テストの依存関係を解決する

巴扎黑
巴扎黑オリジナル
2017-08-16 09:31:242036ブラウズ


要約: 私は長い間単体テストの概念について知っており、試してみて、単体テストと PHPUnit について明確に理解し、ゆっくりと単体テストを実践し始めました。 。 Laravel の依存関係については皆さんご存知のとおり、Laravel は IoC を使用するため、さまざまなモジュールが分離されています。それはまさにこのためです...

私は長い間単体テストの概念について知っていて、ゆっくりと単体テストと PHPUnit について明確に理解し、少しずつ試してきました。単体テストの練習を始めました。

Laravel の依存関係

Laravel が IoC を使用しているため、さまざまなモジュールが分離されていることは誰もが知っています。これがあるからこそ、Laravel で単体テストを書くのが簡単になります。

例として

次のシナリオを考えてみましょう。開発中に、コントローラーとモデルの間に Repository 来处理数据。那么我们的 Controller 就会依赖 Respository。利用 Laravel 的 IoC,我们可以定义一个 Service Provider 来集中将 Respository を追加し、コンテナーに注入することがあります。

製品情報を記録するこのようなリポジトリがあるとします。コントローラーで特定の製品情報を取得し、いくつかのビジネス ロジックを実行したいとします。

Class GoodRepository{    public function getGoodById($goodId)
    {        // TODO: Get good by its id.
    }
}class GoodController extends Controller{    public function show($id, GoodRepository $goodRepository)
    {        // TODO: Do something with good info from that repository.
    }
}// In route/api.phpRoute::get('/api/good/{id}', 'GoodController@show');// Create a RepositoriesServiceProvider in Provider/RepositoriesServiceProvider.php。// And inject the GoodRepository into Container.class RepositoriesServiceProvider extends ServiceProvider{    public function boot()
    {
    
    }    
    public function register()
    {        $this->app->singleton(GoodRepository::class);
    }
}

わかりました、GoodControllerグッドリポジトリ および GoodRepository はデータベース内のデータに依存します。ただし、単体テストを行うときは、生成される依存関係をできるだけ少なくしたいと考えています。したがって、 GoodRepository データが返されました。 GoodController 是依赖 GoodRepository 的,而 GoodRepository 是依赖数据库中的数据的。可是我们在做单元测试的时候,希望尽可能少的产生依赖。所以,我们应该希望能够掌控 GoodRepository 所返回的数据。

在 Laravel,提供了 $this->get('/path/to/route');

Laravel では、$this->get('/path/to/route' ); メソッドを使用して HTTP リクエストをテストします。このテストには必然的に、先ほど述べた依存関係が関係します。この依存関係の問題を解決する方法は、主人公であるスタブウェアに尋ねることができます。

スタブ

(オプションで) 設定された戻り値を返すテストダブルでオブジェクトを置き換える実用的な方法は、スタブと呼ばれます。 🎜

これはPHPUnitのドキュメントからの説明です。私の理解では、いわゆるスタブは依存クラスの動作をシミュレートし、この動作が何を行うかは私たち自身の制御下にあるということです。たとえば、上記の状況では、 GoodRepository の getGoodById メソッドは、外部データ ソースに依存せずに実際の戻り構造と同じ値を返します。 。 GoodRepository 的 getGoodById 方法返回与真正的返回结构相同的值,而不需要依赖外部数据源。

在 Laravel 中使用桩件

我们通过 Service Provider 注册了 GoodRepository 单例,那么按照这个思路,我们在写单元测试的时候,就可以将我们定义的桩件,注册为 GoodRepository

サービス プロバイダー が登録されました。パディング: 2px 4px; ボーダー半径: 4px; カラー: rgb(199, 37, 78); フォントファミリー: "Source Code Pro"、Consolas、Menlo、Monaco、フォントサイズ: 0.93 em; box-sizing: border-box; background-color: rgb(249, 242, 244);">GoodRepository シングルトンの場合、単体テストを作成するとき、定義したスタブは次のようになります。 <code style="padding: 2px 4px; border-radius: 4px; color: rgb(199, 37, 78); font-family: " source code pro new rgb>GoodRepository シングルトン。 🎜
class GoodControllerTest extends TestCase{    public function testShow()
    {
        $data = []; // The data returns from GoodRepository::getGoodById.
        
        $stub = $this->createMock(GoodRepository::class);
        
        $stub->method('getGoodById')->will($this->returnValue($data));        
        $this->app->singleton(GoodRepository::class, function () use ($stub) {            return $stub;
        });
        
        $response = $this->get('/api/good/1');        
        // Some assertions.
    }
}

我们通过在这里将桩件 $stub 用单例模式注册给了 Container,在调用 $this->get('/api/good/1'); 时原本在 Controller 中的 GoodRepository 依赖就变成了我们自定义的桩件 $stub。我们将 $data 定义为和返回值相同的结构,注册到桩件中。这样,所有的数据都在我们可控的范围了。

如果我们在这里不使用桩件,而是直接依赖外部(数据库)中的数据,那么如果 id 为 1 的数据被删除了,我们是不是就要改成 2 了呢?我们是不是就要重新计算数据了匹配断言了呢?这样的测试,可靠性便大大降低。

追記

信頼性の高いシステムには単体テストが不可欠です。幸いなことに、PHPUnit は便利な単体テストを提供します。この記事で説明していることは、PHPUnit のバケツの一滴にすぎません。そして私自身もゆっくりと模索し、実践しています。一緒に励ましましょう。

以上がLaravel チュートリアル: スタブを使用して単体テストの依存関係を解決するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。