I want to test one of my Model classes, so i have to insert, update and delete data from my database in order to test if my methods work well.
I am working with a defined Test database where i have already some data.
To test all methos i use two roles, the admin one and the user one. So i get their data using the setUp method like this:
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'];
}
When i want to test methods like the “banAccess” one who moves data from the Users table to the bannedUsers table, then i have a problem because the Test won’t run well the next time as the user i selected for the Test won’t be in the same table.
It seems that setUP() and tearDown() methods are only executed once after all test methods are called.
This way, if the bannAccess test methods is executed before the testGetUserName method, for example, this last one will fail as the user is not on Users table.
For the moment i am testing the method and deleting the user after it in order to solve this problem but i am sure it have to be a better way to do it:
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']);
}
Thanks.
Your whole test setup is not good. You should use fixtures for that an have the records present in the fixtures. See http://book.cakephp.org/2.0/en/development/testing.html#fixtures
setUp() and tearDown() are executed only one time while startTest() and endTest() are for each test*() method.
Further you should not use query() because it is potentially unsafe because of SQL injections. The CakePHP ORM will take care of that if you would use it… To see query() present in the test make me think you’ve used it in the app to and built a pretty unsafe app.
Also why do you have to copy users to another table instead simply flagging them as banned with a simple tinyint field?