2013-07-24 5 views
9

私は小さなスリムフレームワークアプリケーションのためのいくつかのPHPUnitテストを書こうとしていますが、完全なリクエストを行い、レスポンスをアサートする方法を指すドキュメントのどこにも表示されませんテキストまたは200のステータスを含む、または何か、本当に)。Slim Frameworkエンドポイントユニットテスト

これを実行する方法はありますか?

+0

は、過去12ヶ月以内にヘルプフォーラムで議論されましたが、これまでに解決されたかどうかは不明です。http://help.slimframework.com/discussions/questions/222-how-to-test-a-silm -app – Kristian

答えて

3

私は大雑把にそれを動作させることができました。次に、エンドポイント・テスト・クラスの例を示します。

開発環境で作業していると仮定すると、自分のローカルホストにcurlリクエストを実行して、レポにコミットする前にテストすることができます。

まず、作成するクラス:これを使用するには

class ApiEndpointsTest extends PHPUnit_Framework_TestCase 
{ 
    protected $api_url = "http://localhost/api/v1"; 

    //create a function that will allow you to call API endpoints at-will. 
    private function loadEndpoint($url) { 
     $ch = curl_init(); 
     curl_setopt($ch, CURLOPT_URL, $url); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
     $output = curl_exec($ch); 
     $info = curl_getinfo($ch); 
     curl_close($ch); 
     return array(
      'body' => $output, 
      'info' => $info 
     ); 
    } 

    //this allows you to write messages in the test output 
    private function printToConsole($statement) { 
     fwrite(STDOUT, $statement."\n"); 
    } 

、あなたが特定のエンドポイントの応答をテスト関数を書くことができます。

//this will test the actual body of the response against something expected. 
public function testGetUserResponse() { 
    $this->printToConsole(__METHOD__); 
    $url = $this->api_url."https://stackoverflow.com/users/124"; 
    $response = $this->loadEndpoint($url); 
    $expected = '[{"name":"John Smith","email":"[email protected]"}]'; 
    $this->assertEquals($response['body'], $expected); 
} 

を別のテストでは、他のプロパティをテストすることができますAPIコールの応答:

public function testGetUserMimeType() { 
    $this->printToConsole(__METHOD__); 
    $url = $this->api_url."https://stackoverflow.com/users/124"; 
    $response = $this->loadEndpoint($url); 
    $this->assertEquals($response['info']['content_type'], 'application/json'); 
} 

あなたの情報プロパティのオプションは次のとおりです。 http://php.net/manual/en/function.curl-getinfo.php

サイドノート:これを読んでいる人がPHPUnitのエキスパートであり、より良い方法を知っていれば、私はそれについて学ぶことに興味があります。私はPHPUnitを使い慣れています。ここで

8

は、あなたがあなたのスリムアプリケーションをテストする方法の例です:私たちはそれをテストするにはどうすればよい

<?php 
use Slim\Slim; 

require_once 'vendor/autoload.php'; 

$app = new Slim(); 

$app->get('/', function(){ 
    echo 'home'; 
})->name('home'); 

$app->get('/hello/:name', function($name){ 
    echo "hello $name"; 
})->name('hello'); 

$app->map('/login', function() use($app) { 
    if($app->request()->params('login')) { 
     $app->flash('success', 'Successfully logged in'); 
     $app->redirect($app->urlFor('hello', array('name' => $app->request()->params('login')))); 
    } else { 
     $app->flash('error', 'Wrong login'); 
     $app->redirect($app->urlFor('home')); 
    } 
})->via('GET', 'POST'); 

$app->run(); 

https://github.com/mac2000/SlimTestable

は、我々は簡単なアプリケーションを持っていると仮定しますか?

Appクラスを作成します。私たちは、新しいクラスのコンストラクタにすべての私たちのルートを移動

<?php // src/App.php 
use Slim\Slim; 

class App extends Slim { 
    function __construct(array $userSettings = array()) 
    { 
     parent::__construct($userSettings); 

     $this->get('/', function(){ 
      echo 'home'; 
     })->name('home'); 

     $this->get('/hello/:name', function($name){ 
      echo "hello $name"; 
     })->name('hello'); 

     $this->map('/login', function() { 
      if($this->request()->params('login')) { 
       $this->flash('success', 'Successfully logged in'); 
       $this->redirect($this->urlFor('hello', array('name' => $this->request()->params('login')))); 
      } else { 
       $this->flash('error', 'Wrong login'); 
       $this->redirect($this->urlFor('home')); 
      } 
     })->via('GET', 'POST'); 
    } 

    /** 
    * @return \Slim\Http\Response 
    */ 
    public function invoke() { 
     $this->middleware[0]->call(); 
     $this->response()->finalize(); 
     return $this->response(); 
    } 
} 

お知らせし、またそれは、むしろそれをエコーより応答を返す除いrun方法と同様の操作を行う新しいinvoke方法を、気づきます。あなたはいくつかのことに気づくはずです

<?php // tests/ExampleTest.php 
use Slim\Environment; 

class ExampleTest extends PHPUnit_Framework_TestCase { 
    private $app; 

    public function setUp() 
    { 
     $_SESSION = array(); 
     $this->app = new App(); 
    } 

    public function testHome() { 
     Environment::mock(array(
      'PATH_INFO' => '/' 
     )); 
     $response = $this->app->invoke(); 

     $this->assertContains('home', $response->getBody()); 
    } 

    public function testHello() { 
     Environment::mock(array(
      'PATH_INFO' => '/hello/world' 
     )); 
     $response = $this->app->invoke(); 

     $this->assertTrue($response->isOk()); 
     $this->assertContains('hello world', $response->getBody()); 
    } 

    public function testNotFound() { 
     Environment::mock(array(
      'PATH_INFO' => '/not-exists' 
     )); 
     $response = $this->app->invoke(); 

     $this->assertTrue($response->isNotFound()); 
    } 

    public function testLogin() { 
     Environment::mock(array(
      'PATH_INFO' => '/login' 
     )); 
     $response = $this->app->invoke(); 

     $this->assertTrue($response->isRedirect()); 
     $this->assertEquals('Wrong login', $_SESSION['slim.flash']['error']); 
     $this->assertEquals('/', $response->headers()->get('Location')); 
    } 

    public function testPostLogin() { 
     Environment::mock(array(
      'REQUEST_METHOD' => 'POST', 
      'PATH_INFO' => '/login', 
      'slim.input' => 'login=world' 
     )); 
     $response = $this->app->invoke(); 

     $this->assertTrue($response->isRedirect()); 
     $this->assertEquals('Successfully logged in', $_SESSION['slim.flash']['success']); 
     $this->assertEquals('/hello/world', $response->headers()->get('Location')); 
    } 

    public function testGetLogin() { 
     Environment::mock(array(
      'PATH_INFO' => '/login', 
      'QUERY_STRING' => 'login=world' 
     )); 
     $response = $this->app->invoke(); 

     $this->assertTrue($response->isRedirect()); 
     $this->assertEquals('Successfully logged in', $_SESSION['slim.flash']['success']); 
     $this->assertEquals('/hello/world', $response->headers()->get('Location')); 
    } 
} 

テストを設定しながら

<?php 
require_once 'vendor/autoload.php'; 

$app = new App(); 
$app->run(); 

そして今、それはテストのための時間です:

今、あなたのindex.phpファイルには、このいずれかのようであるかもしれませんテストのために$_SESSION配列を作成し、Appクラスオブジェクトをインスタンス化します。

runではなく、テストでは同じことを行うinvokeを呼び出していますが、応答オブジェクトを返します。

Environment::mock私たちのアプリケーションで処理されるリクエストを模擬するために使用されます。