Removing code from CakeTestCase around the method "testAction" which was a bad way of testing controllers, often making it more difficult.

This also removes class contamination in newly created test cases
This commit is contained in:
José Lorenzo Rodríguez 2010-05-05 22:42:56 -04:30
parent b53d21ff52
commit bed87b87c6
3 changed files with 17 additions and 425 deletions

View file

@ -27,11 +27,11 @@ if (!class_exists('AppController')) {
define('APP_CONTROLLER_EXISTS', true);
}
Mock::generate('CakeHtmlReporter');
Mock::generate('CakeTestCase', 'CakeDispatcherMockTestCase');
//Mock::generate('CakeHtmlReporter');
//Mock::generate('CakeTestCase', 'CakeDispatcherMockTestCase');
SimpleTest::ignore('SubjectCakeTestCase');
SimpleTest::ignore('CakeDispatcherMockTestCase');
//SimpleTest::ignore('SubjectCakeTestCase');
//SimpleTest::ignore('CakeDispatcherMockTestCase');
/**
* SubjectCakeTestCase
@ -41,18 +41,6 @@ SimpleTest::ignore('CakeDispatcherMockTestCase');
*/
class SubjectCakeTestCase extends CakeTestCase {
/**
* Feed a Mocked Reporter to the subject case
* prevents its pass/fails from affecting the real test
*
* @param string $reporter
* @access public
* @return void
*/
function setReporter(&$reporter) {
$this->_reporter = &$reporter;
}
/**
* testDummy method
*
@ -78,10 +66,9 @@ class CakeTestCaseTest extends CakeTestCase {
*/
function setUp() {
$this->_debug = Configure::read('debug');
$this->Case =& new SubjectCakeTestCase();
$reporter =& new MockCakeHtmlReporter();
$this->Case->setReporter($reporter);
$this->Reporter = $reporter;
$this->Case = new SubjectCakeTestCase();
$this->Result = new PHPUnit_Framework_TestResult;
$this->Reporter = $this->getMock('CakeHtmlReporter');
}
/**
@ -93,6 +80,7 @@ class CakeTestCaseTest extends CakeTestCase {
function tearDown() {
Configure::write('debug', $this->_debug);
unset($this->Case);
unset($this->Result);
unset($this->Reporter);
}
@ -113,8 +101,7 @@ class CakeTestCaseTest extends CakeTestCase {
* @return void
*/
function testAssertGoodTags() {
$this->Reporter->expectAtLeastOnce('paintPass');
$this->Reporter->expectNever('paintFail');
$this->Reporter->expects($this->atLeastOnce())->method('paintPass');
$input = '<p>Text</p>';
$pattern = array(
@ -122,7 +109,7 @@ class CakeTestCaseTest extends CakeTestCase {
'Text',
'/p',
);
$this->assertTrue($this->Case->assertTags($input, $pattern));
$this->Case->assertTags($input, $pattern);
$input = '<a href="/test.html" class="active">My link</a>';
$pattern = array(
@ -250,8 +237,8 @@ class CakeTestCaseTest extends CakeTestCase {
* @return void
*/
function testBadAssertTags() {
$this->Reporter->expectAtLeastOnce('paintFail');
$this->Reporter->expectNever('paintPass');
// $this->Reporter->expectAtLeastOnce('paintFail');
// $this->Reporter->expectNever('paintPass');
$input = '<a href="/test.html" class="active">My link</a>';
$pattern = array(
@ -331,137 +318,6 @@ class CakeTestCaseTest extends CakeTestCase {
$this->assertEqual(array_slice($result, -2), array('endCase', 'end'));
}
/**
* TestTestAction
*
* @access public
* @return void
*/
function testTestAction() {
App::build(array(
'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS),
'models' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'models' . DS),
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS),
'controllers' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'controllers' . DS)
), true);
$result = $this->Case->testAction('/tests_apps/index', array('return' => 'view'));
$this->assertPattern('/This is the TestsAppsController index view/', $result);
$result = $this->Case->testAction('/tests_apps/index', array('return' => 'contents'));
$this->assertPattern('/This is the TestsAppsController index view/', $result);
$this->assertPattern('/<html/', $result);
$this->assertPattern('/<\/html>/', $result);
$result = $this->Case->testAction('/tests_apps/some_method', array('return' => 'result'));
$this->assertEqual($result, 5);
$result = $this->Case->testAction('/tests_apps/set_action', array('return' => 'vars'));
$this->assertEqual($result, array('var' => 'string'));
$db =& ConnectionManager::getDataSource('test_suite');
$fixture =& new PostFixture();
$fixture->create($db);
$result = $this->Case->testAction('/tests_apps_posts/add', array('return' => 'vars'));
$this->assertTrue(array_key_exists('posts', $result));
$this->assertEqual(count($result['posts']), 1);
$result = $this->Case->testAction('/tests_apps_posts/url_var/var1:value1/var2:val2', array(
'return' => 'vars',
'method' => 'get',
));
$this->assertTrue(isset($result['params']['url']['url']));
$this->assertEqual(array_keys($result['params']['named']), array('var1', 'var2'));
$result = $this->Case->testAction('/tests_apps_posts/url_var/gogo/val2', array(
'return' => 'vars',
'method' => 'get',
));
$this->assertEqual($result['params']['pass'], array('gogo', 'val2'));
$result = $this->Case->testAction('/tests_apps_posts/url_var', array(
'return' => 'vars',
'method' => 'get',
'data' => array(
'red' => 'health',
'blue' => 'mana'
)
));
$this->assertTrue(isset($result['params']['url']['red']));
$this->assertTrue(isset($result['params']['url']['blue']));
$this->assertTrue(isset($result['params']['url']['url']));
$result = $this->Case->testAction('/tests_apps_posts/post_var', array(
'return' => 'vars',
'method' => 'post',
'data' => array(
'name' => 'is jonas',
'pork' => 'and beans',
)
));
$this->assertEqual(array_keys($result['data']), array('name', 'pork'));
$fixture->drop($db);
$db =& ConnectionManager::getDataSource('test_suite');
$_backPrefix = $db->config['prefix'];
$db->config['prefix'] = 'cake_testaction_test_suite_';
$config = $db->config;
$config['prefix'] = 'cake_testcase_test_';
ConnectionManager::create('cake_test_case', $config);
$db2 =& ConnectionManager::getDataSource('cake_test_case');
$fixture =& new PostFixture($db2);
$fixture->create($db2);
$fixture->insert($db2);
$result = $this->Case->testAction('/tests_apps_posts/fixtured', array(
'return' => 'vars',
'fixturize' => true,
'connection' => 'cake_test_case',
));
$this->assertTrue(isset($result['posts']));
$this->assertEqual(count($result['posts']), 3);
$tables = $db2->listSources();
$this->assertFalse(in_array('cake_testaction_test_suite_posts', $tables));
$fixture->drop($db2);
$db =& ConnectionManager::getDataSource('test_suite');
//test that drop tables behaves as exepected with testAction
$db =& ConnectionManager::getDataSource('test_suite');
$_backPrefix = $db->config['prefix'];
$db->config['prefix'] = 'cake_testaction_test_suite_';
$config = $db->config;
$config['prefix'] = 'cake_testcase_test_';
ConnectionManager::create('cake_test_case', $config);
$db =& ConnectionManager::getDataSource('cake_test_case');
$fixture =& new PostFixture($db);
$fixture->create($db);
$fixture->insert($db);
$this->Case->dropTables = false;
$result = $this->Case->testAction('/tests_apps_posts/fixtured', array(
'return' => 'vars',
'fixturize' => true,
'connection' => 'cake_test_case',
));
$tables = $db->listSources();
$this->assertTrue(in_array('cake_testaction_test_suite_posts', $tables));
$fixture->drop($db);
$db =& ConnectionManager::getDataSource('test_suite');
$db->config['prefix'] = $_backPrefix;
$fixture->drop($db);
}
/**
* testSkipIf
*
@ -471,31 +327,5 @@ class CakeTestCaseTest extends CakeTestCase {
$this->assertTrue($this->Case->skipIf(true));
$this->assertFalse($this->Case->skipIf(false));
}
/**
* testTestDispatcher
*
* @access public
* @return void
*/
function testTestDispatcher() {
App::build(array(
'plugins' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'plugins' . DS),
'models' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'models' . DS),
'views' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'views' . DS),
'controllers' => array(TEST_CAKE_CORE_INCLUDE_PATH . 'tests' . DS . 'test_app' . DS . 'controllers' . DS)
), true);
$Dispatcher =& new CakeTestDispatcher();
$Case =& new CakeDispatcherMockTestCase();
$Case->expectOnce('startController');
$Case->expectOnce('endController');
$Dispatcher->testCase($Case);
$this->assertTrue(isset($Dispatcher->testCase));
$return = $Dispatcher->dispatch('/tests_apps/index', array('autoRender' => 0, 'return' => 1, 'requested' => 1));
}
}
?>

View file

@ -17,64 +17,9 @@
* @since CakePHP(tm) v 1.2.0.4667
* @license http://www.opensource.org/licenses/opengroup.php The Open Group Test Suite License
*/
if (!class_exists('dispatcher')) {
require CAKE . 'dispatcher.php';
}
require_once CAKE_TESTS_LIB . 'cake_test_model.php';
require_once CAKE_TESTS_LIB . 'cake_test_fixture.php';
App::import('Vendor', 'simpletest' . DS . 'unit_tester');
/**
* CakeTestDispatcher
*
* @package cake
* @subpackage cake.cake.tests.lib
*/
class CakeTestDispatcher extends Dispatcher {
/**
* controller property
*
* @var Controller
* @access public
*/
public $controller;
public $testCase;
/**
* testCase method
*
* @param CakeTestCase $testCase
* @return void
*/
public function testCase(&$testCase) {
$this->testCase =& $testCase;
}
/**
* invoke method
*
* @param Controller $controller
* @param array $params
* @param boolean $missingAction
* @return Controller
*/
protected function _invoke(&$controller, $params, $missingAction = false) {
$this->controller =& $controller;
if (isset($this->testCase) && method_exists($this->testCase, 'startController')) {
$this->testCase->startController($this->controller, $params);
}
$result = parent::_invoke($this->controller, $params, $missingAction);
if (isset($this->testCase) && method_exists($this->testCase, 'endController')) {
$this->testCase->endController($this->controller, $params);
}
return $result;
}
}
/**
* CakeTestCase class
@ -198,189 +143,6 @@ class CakeTestCase extends PHPUnit_Framework_TestCase {
return $shouldSkip;
}
/**
* Callback issued when a controller's action is about to be invoked through testAction().
*
* @param Controller $controller Controller that's about to be invoked.
* @param array $params Additional parameters as sent by testAction().
* @return void
*/
public function startController(&$controller, $params = array()) {
if (isset($params['fixturize']) && ((is_array($params['fixturize']) && !empty($params['fixturize'])) || $params['fixturize'] === true)) {
if (!isset($this->db)) {
$this->_initDb();
}
if ($controller->uses === false) {
$list = array($controller->modelClass);
} else {
$list = is_array($controller->uses) ? $controller->uses : array($controller->uses);
}
$models = array();
ClassRegistry::config(array('ds' => $params['connection']));
foreach ($list as $name) {
if ((is_array($params['fixturize']) && in_array($name, $params['fixturize'])) || $params['fixturize'] === true) {
if (class_exists($name) || App::import('Model', $name)) {
$object =& ClassRegistry::init($name);
//switch back to specified datasource.
$object->setDataSource($params['connection']);
$db =& ConnectionManager::getDataSource($object->useDbConfig);
$db->cacheSources = false;
$models[$object->alias] = array(
'table' => $object->table,
'model' => $object->alias,
'key' => strtolower($name),
);
}
}
}
ClassRegistry::config(array('ds' => 'test_suite'));
if (!empty($models) && isset($this->db)) {
$this->_actionFixtures = array();
foreach ($models as $model) {
$fixture =& new CakeTestFixture($this->db);
$fixture->name = $model['model'] . 'Test';
$fixture->table = $model['table'];
$fixture->import = array('model' => $model['model'], 'records' => true);
$fixture->init();
$fixture->create($this->db);
$fixture->insert($this->db);
$this->_actionFixtures[] =& $fixture;
}
foreach ($models as $model) {
$object =& ClassRegistry::getObject($model['key']);
if ($object !== false) {
$object->setDataSource('test_suite');
$object->cacheSources = false;
}
}
}
}
}
/**
* Callback issued when a controller's action has been invoked through testAction().
*
* @param Controller $controller Controller that has been invoked.
* @param array $params Additional parameters as sent by testAction().
* @return void
*/
public function endController(&$controller, $params = array()) {
if (isset($this->db) && isset($this->_actionFixtures) && !empty($this->_actionFixtures) && $this->dropTables) {
foreach ($this->_actionFixtures as $fixture) {
$fixture->drop($this->db);
}
}
}
/**
* Executes a Cake URL, and can get (depending on the $params['return'] value):
*
* Params:
* - 'return' has several possible values:
* 1. 'result': Whatever the action returns (and also specifies $this->params['requested'] for controller)
* 2. 'view': The rendered view, without the layout
* 3. 'contents': The rendered view, within the layout.
* 4. 'vars': the view vars
*
* - 'fixturize' - Set to true if you want to copy model data from 'connection' to the test_suite connection
* - 'data' - The data you want to insert into $this->data in the controller.
* - 'connection' - Which connection to use in conjunction with fixturize (defaults to 'default')
* - 'method' - What type of HTTP method to simulate (defaults to post)
*
* @param string $url Cake URL to execute (e.g: /articles/view/455)
* @param mixed $params Parameters (see above), or simply a string of what to return
* @return mixed Whatever is returned depending of requested result
*/
public function runTestAction($url, $params = array()) {
$default = array(
'return' => 'result',
'fixturize' => false,
'data' => array(),
'method' => 'post',
'connection' => 'default'
);
if (is_string($params)) {
$params = array('return' => $params);
}
$params = array_merge($default, $params);
$toSave = array(
'case' => null,
'group' => null,
'app' => null,
'output' => null,
'show' => null,
'plugin' => null
);
$this->__savedGetData = (empty($this->__savedGetData))
? array_intersect_key($_GET, $toSave)
: $this->__savedGetData;
$data = (!empty($params['data'])) ? $params['data'] : array();
if (strtolower($params['method']) == 'get') {
$_GET = array_merge($this->__savedGetData, $data);
$_POST = array();
} else {
$_POST = array('data' => $data);
$_GET = $this->__savedGetData;
}
$return = $params['return'];
$params = array_diff_key($params, array('data' => null, 'method' => null, 'return' => null));
$dispatcher =& new CakeTestDispatcher();
$dispatcher->testCase($this);
if ($return != 'result') {
if ($return != 'contents') {
$params['layout'] = false;
}
ob_start();
@$dispatcher->dispatch($url, $params);
$result = ob_get_clean();
if ($return == 'vars') {
$view =& ClassRegistry::getObject('view');
$viewVars = $view->getVars();
$result = array();
foreach ($viewVars as $var) {
$result[$var] = $view->getVar($var);
}
if (!empty($view->pageTitle)) {
$result = array_merge($result, array('title' => $view->pageTitle));
}
}
} else {
$params['return'] = 1;
$params['bare'] = 1;
$params['requested'] = 1;
$result = @$dispatcher->dispatch($url, $params);
}
if (isset($this->_actionFixtures)) {
unset($this->_actionFixtures);
}
ClassRegistry::flush();
return $result;
}
/**
* Announces the start of a test.
*

View file

@ -318,9 +318,9 @@ class CakeHtmlReporter extends CakeBaseReporter implements PHPUnit_Framework_Tes
'] in ['. $exception->getFile() .
' line ' . $exception->getLine() . ']';
echo "<div class='msg'>" . $this->_htmlEntities($message) . "</div>\n";
$breadcrumb = $this->getTestList();
array_shift($breadcrumb);
echo "<div>" . implode(" -&gt; ", $breadcrumb) . "</div>\n";
//$breadcrumb = $this->getTestList();
//array_shift($breadcrumb);
//echo "<div>" . implode(" -&gt; ", $breadcrumb) . "</div>\n";
echo "</li>\n";
}
@ -386,7 +386,7 @@ class CakeHtmlReporter extends CakeBaseReporter implements PHPUnit_Framework_Tes
* @param float $time
*/
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {
$this->paintException($e);
}
/**