From 1ae178334023d36a224b06c371a47a5c3e0aad3d Mon Sep 17 00:00:00 2001 From: wei <> Date: Mon, 14 May 2007 02:51:03 +0000 Subject: remove unfinished docs. --- .../pages/Docs/UserClassAndExceptions.page | 202 --------------------- 1 file changed, 202 deletions(-) delete mode 100644 demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page (limited to 'demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page') diff --git a/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page b/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page deleted file mode 100644 index f85e00be..00000000 --- a/demos/time-tracker/protected/pages/Docs/UserClassAndExceptions.page +++ /dev/null @@ -1,202 +0,0 @@ - -

More complete ProjectTestCase

-

-In creating a new project, we need to check the following: -

-So to perform this task, we will modified the test code. - -function testProjectDaoCanCreateNewProject() -{ - $project = new Project(); - $project->ID = 1; - $project->Name = "Project 1"; - $project->CreatorUserName = "Customer A"; - $project->ManagerUserName = "Manager A"; - - $customer = new TimeTrackerUser(); - $customer->ID = 1; - $customer->Name = "Customer A"; - - $manager = new TimeTrackerUser(); - $manager->ID = 2; - $manager->Name = "Manager A"; - - if(($conn = $this->connection) instanceof MockTSqlMapper) - { - //return the customer and manager - $conn->setReturnValue('queryForObject', - $customer, array('GetUserByName', 'Customer A')); - $conn->setReturnValue('queryForObject', - $manager, array('GetUserByName', 'Manager A')); - - //project does not exist - $conn->setReturnValue('queryForObject', - null, array('GetProjectByName', 'Project 1')); - - $param['project'] = $project; - $param['creator'] = $customer->ID; - $param['manager'] = $manager->ID; - - $conn->setReturnValue('insert', true, - array('CreateNewProject', $param)); - $conn->setReturnReference('queryForObject', - $project, array('GetProjectByID', 1)); - - //we expect queryForObject to be called 3 times - $conn->expectMinimumCallCount('queryForObject', 3); - $conn->expectAtLeastOnce('insert'); - } - - $this->assertTrue($this->dao->createNewProject($project)); - $this->assertEqual($this->dao->getProjectByID(1), $project); -} - -

-

It may seem very weird that there is so much code in the tests -and why we even bother to write all these test codes. Well, using the -above test code we have the following advantages.

-
Advantages of Mock -
    -
  1. we don't need a real database base connection to test the code, - this means we can start relying on tested code ealier
  2. -
  3. when a test fails we know that problem is not part of the database
  4. -
  5. when a test fail, we can quickly pin point the problem
  6. -
  7. the test suite gives us the confidence to refactor our code
  8. -
-
- -

Of couse, the test will not be able to cover the higher interactions, such as -the user interface, so intergration or functional web test will be used later on. -

- -

So how did we come up with the above tests? We started simple, then we -ask what sort of things it should handle. We assume that the connection object -work as expect or known to be unexpected and see how the method we want to test handle -these situations.

- -

If we run the above test, we will be faced with numerous errors. First will be -that the TimeTrackerUser can not be found.

- -

Creating a new User Class

-

Notice that the Project class contains CreatorUserName -and ManagerUserName properties. So at some point we -are going to need at least one User class. We shall name the class as -TimeTrackerUser and save it as APP_CODE/TimeTrackerUser.php - -<?php -Prado::using('System.Security.TUser'); -Prado::using('System.Security.TUserManager'); -class TimeTrackerUser extends TUser -{ - private $_ID; - - public function __construct() - { - parent::__construct(new TUserManager()); - } - - public function getID(){ return $this->_ID; } - - public function setID($value) - { - if(is_null($this->_ID)) - $this->_ID = $value; - else - throw new TimeTrackerUserException( - 'timetracker_user_readonly_id'); - } -} -?> - - -

Custom Exceptions

-

We enforce that the ID of the user to be read-only once it has been -set by throwing a custom exception. Prado's exception classes -uses a string key to find a localized exception string containing more -detailed description of the exception. The default exception messages -are stored in the framework/Exceptions/messages.txt. This -file location can be changed by overriding the getErrorMessageFile() -method of TException class. We define a custom exception class -for all Time Tracker application exceptions as TimeTrackerException -and save the class as APP_CODE/TimeTrackerException.php.

- - -<?php -class TimeTrackerException extends TException -{ - /** - * @return string path to the error message file - */ - protected function getErrorMessageFile() - { - return dirname(__FILE__).'/exceptions.txt'; - } -} -?> - - -

We then create a exceptions.txt file in the APP_CODE -directory with the following content.

- - -timetracker_user_readonly_id = Time tracker user ID is read-only. - - -

Additional parameters passed in the exception constructor can be -added the message string using {0} as the first additional parameter, -and {1} as the second additional parameter, and so on. -For example, suppose we want to raise the follow exception. -

- - -throw new TimeTrackerException('project_exists', $projectName); - - -

The exception error message in exceptions.txt may contain something like:

- -project_exists = Time tracker project '{0}' already exists. - - -

Completing the test case

-

From the unit test code, we can pretty much see what the implementation -for createNewProject() will look like.

- - -public function createNewProject($project) -{ - $sqlmap = $this->getConnection(); - $creator = $sqlmap->queryForObject('GetUserByName', $project->CreatorUserName); - $manager = $sqlmap->queryForObject('GetUserByName', $project->ManagerUserName); - $exists = $sqlmap->queryForObject('GetProjectByName', $project->Name); - if($exists) - { - throw new TimeTrackerException( - 'project_exists', $project->Name); - } - else if(!$creator || !$manager) - { - throw new TimeTrackerException( - 'invalid_creator_and_manager', - $project->Name, $project->CreatorUserName, - $project->ManagerUserName); - } - else - { - $param['project'] = $project; - $param['creator'] = $creator->ID; - $param['manager'] = $manager->ID; - return $sqlmap->insert('CreateNewProject', $param); - } -} - - -
Tip: -A hierachy of exception class can be used to have fine exception handling. -Since this is a small project and for simplicity, we shall use the application level -TimeTrackerException exception class for most exception cases. -
- -
\ No newline at end of file -- cgit v1.2.3