2012-04-10 9 views
0

私のモデルクラスをテストしたいので、メソッドがうまく動作するかどうかをテストするためにデータベースからデータを挿入、更新、削除する必要があります。CakePHP 2.0によるデータベーステスト

私は既にいくつかのデータがある定義済みのテストデータベースを使って作業しています。 すべてのメトスをテストするには、管理者とユーザーの2つの役割を使用します。だから、私はこのような設定方法を使用してデータを取得:

public function setUp() { 
    parent::setUp(); 
    $this->User = ClassRegistry::init('User'); 

    $admin = $this->User->query("select * from users where admin = 1"); 
    $this->testUser['admin']['id'] = $admin[0]['users']['id']; 
    $this->testUser['admin']['username'] = $admin[0]['users']['username']; 
    $this->testUser['admin']['password'] = $admin[0]['users']['password']; 
    $this->testUser['admin']['verified'] = $admin[0]['users']['verified']; 
    $this->testUser['admin']['created'] = $admin[0]['users']['created']; 
    $this->testUser['admin']['nick'] = $admin[0]['users']['nick']; 
    $this->testUser['admin']['admin'] = $admin[0]['users']['admin']; 

    $user = $this->User->query("select * from users where admin = 0 and verified = 0"); 

    $this->testUser['user']['id'] = $user[0]['users']['id']; 
    $this->testUser['user']['username'] = $user[0]['users']['username']; 
    $this->testUser['user']['password'] = $user[0]['users']['password']; 
    $this->testUser['user']['verified'] = $user[0]['users']['verified']; 
    $this->testUser['user']['created'] = $user[0]['users']['created']; 
    $this->testUser['user']['nick'] = $user[0]['users']['nick']; 
    $this->testUser['user']['admin'] = $user[0]['users']['admin']; 

} 

私はbannedUsersテーブルへのユーザーのテーブルからデータを移動し、「banAccess」のようなメソッドをテストしたい場合は、その後、私はので、問題を抱えていますテスト用に選択したユーザーが同じテーブルにないため、次回はテストがうまく実行されません。 setUP()メソッドとtearDown()メソッドは、すべてのテストメソッドが呼び出された後に1回だけ実行されるようです。 このようにして、bannAccessテストメソッドがtestGetUserNameメソッドの前に実行された場合、たとえば、この最後のテストメソッドはユーザーがUsersテーブルにないため失敗します。瞬間のために

私は方法をテストし、それの後にユーザーを削除この問題を解決するために、私はそれはそれを行うには良い方法である必要はあり確信しています:

public function testBanAccess() { 
    $result = $this->User->banAccess($this->testUser['user']['id'], 'spam', '42'); 
    $expected = true; 

    $this->assertEquals($expected, $result); 

    $this->User->query("delete from banUsers where id = ".$this->testUser['user']['id']); 
} 

感謝を。

答えて

1

あなたの全体的なテストの設定は良くありません。フィクスチャにあるレコードを持つフィクスチャを使用する必要があります。 http://book.cakephp.org/2.0/en/development/testing.html#fixtures

setUp()とtearDown()はstartTest()とendTest()がtest *()メソッドごとに1回だけ実行されます。

さらにあなたべきない使用クエリ()、それが原因でSQLインジェクションの潜在的に危険ですので。 CakePHP ORMは、もしあなたがそれを使うなら、世話をします...テスト中に存在するquery()を見れば、あなたはそれをアプリで使ったと思って、かなり安全でないアプリを構築したと思います。

なぜ単純なtinyintフィールドで禁止されているのではなく、別のテーブルにユーザーをコピーする必要がありますか?

+0

あなたは本当ですか、burzum?私はかつてcake2用のテストスクリプトを書いてくれました。私はsetUpとtearDownが各starTest/endTestの前後に実行され、したがって各test *メソッドの前後にも実行されていると教えてくれました。 – mark

+0

ええ、私はすべてのモデルの中で$ this-> queryを使用しています。それ以外に何が使えますか? 備品については、DBから取得するのではなく、すべてのデータを書き直すのがちょっと退屈なようです... 今、私は今何をしているのですか、私はstartTestとendTestを使うべきですか? また、「reason」、「expireDate」などのフィールドがあるため、別のテーブルに移動しています。と私はそれ以外の禁止されているユーザーの残りの部分でNULLにそれらの2つのフィールドを持ってほしくない場合は、より良いDBデザインだと思う。 – Alvaro

+0

@markすべてのメソッドを覚えることができないので、私がここに投稿する前にそのAPIをチェックしました。しかし、私は今日後で時間があるときにコードをチェックします。スティーブ私は、dbデザインについては、あなたはちょうど2つの非常に似たようなモデルと非常に可能性が重複するコードで終わることに同意します。 query()以外の何か?フレームワークとは何かを読んだことはありますか? http://book.cakephp.org/2.0/ja/models.htmlこちらからお読みください。 Model :: find()をすべて使用する必要があります。適切なエスケープ処理が行われ、mysqlからoracle(適切に使用されている場合)に切り替えるとコードは引き続き機能します。 – burzum