From 9b9e886df69d4fda9ded9daffc8dfe9b3752af5f Mon Sep 17 00:00:00 2001 From: mark_story Date: Sun, 12 Oct 2014 22:14:47 -0400 Subject: [PATCH] Fix getMockForModel() using the incorrect datasource. Because getMockForModel() does not go through the test datasource injection in ClassRegistry::init() we need to duplicate the basics of that logic here. Thankfully, we already have a mock so we can do that datasource switching without reflection. Of course this means there will be limitations to how/when this will work, but I feel those scenarios can probably be solved by not using mocks, or by mocking out the problematic methods. This set of changes makes getMockForModel() work with secondary datasources, as one would expect it to do, but I'm not sure it ever did. Refs #4694 --- .../Test/Case/TestSuite/CakeTestCaseTest.php | 54 ++++++++++++++++--- lib/Cake/TestSuite/CakeTestCase.php | 12 ++++- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/lib/Cake/Test/Case/TestSuite/CakeTestCaseTest.php b/lib/Cake/Test/Case/TestSuite/CakeTestCaseTest.php index 3dfc66926..16e70f777 100644 --- a/lib/Cake/Test/Case/TestSuite/CakeTestCaseTest.php +++ b/lib/Cake/Test/Case/TestSuite/CakeTestCaseTest.php @@ -17,9 +17,25 @@ * @since CakePHP v 1.2.0.4487 * @license http://www.opensource.org/licenses/mit-license.php MIT License */ - +App::uses('CakePlugin', 'Core'); App::uses('Controller', 'Controller'); App::uses('CakeHtmlReporter', 'TestSuite/Reporter'); +App::uses('Model', 'Model'); + +/** + * Secondary Post stub class. + */ +class SecondaryPost extends Model { +/** + * @var string + */ + public $useTable = 'posts'; + +/** + * @var string + */ + public $useDbConfig = 'secondary'; +} /** * CakeTestCaseTest @@ -391,9 +407,9 @@ class CakeTestCaseTest extends CakeTestCase { */ public function testGetMockForModel() { App::build(array( - 'Model' => array( - CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS - ) + 'Model' => array( + CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS + ) ), App::RESET); $Post = $this->getMockForModel('Post'); @@ -408,6 +424,27 @@ class CakeTestCaseTest extends CakeTestCase { $this->assertInternalType('array', $Post->find('all')); } +/** + * Test getMockForModel on secondary datasources. + * + * @return void + */ + public function testGetMockForModelSecondaryDatasource() { + App::build(array( + 'Plugin' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS), + 'Model/Datasource/Database' => array( + CAKE . 'Test' . DS . 'test_app' . DS . 'Model' . DS . 'Datasource' . DS . 'Database' . DS + ) + ), App::RESET); + CakePlugin::load('TestPlugin'); + ConnectionManager::create('test_secondary', [ + 'datasource' => 'Database/TestLocalDriver' + ]); + $post = $this->getMockForModel('SecondaryPost', array('save')); + $this->assertEquals('test_secondary', $post->useDbConfig); + ConnectionManager::drop('test_secondary'); + } + /** * test getMockForModel() with plugin models * @@ -415,9 +452,9 @@ class CakeTestCaseTest extends CakeTestCase { */ public function testGetMockForModelWithPlugin() { App::build(array( - 'Plugin' => array( - CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS - ) + 'Plugin' => array( + CAKE . 'Test' . DS . 'test_app' . DS . 'Plugin' . DS + ) ), App::RESET); CakePlugin::load('TestPlugin'); $this->getMockForModel('TestPlugin.TestPluginAppModel'); @@ -425,6 +462,7 @@ class CakeTestCaseTest extends CakeTestCase { $result = ClassRegistry::init('TestPlugin.TestPluginComment'); $this->assertInstanceOf('TestPluginComment', $result); + $this->assertEquals('test', $result->useDbConfig); $TestPluginComment = $this->getMockForModel('TestPlugin.TestPluginComment', array('save')); @@ -445,7 +483,7 @@ class CakeTestCaseTest extends CakeTestCase { * @return void */ public function testGetMockForModelModel() { - $Mock = $this->getMockForModel('Model', array('save'), array('name' => 'Comment')); + $Mock = $this->getMockForModel('Model', array('save', 'setDataSource'), array('name' => 'Comment')); $result = ClassRegistry::init('Comment'); $this->assertInstanceOf('Model', $result); diff --git a/lib/Cake/TestSuite/CakeTestCase.php b/lib/Cake/TestSuite/CakeTestCase.php index 3734e2595..6e76049da 100644 --- a/lib/Cake/TestSuite/CakeTestCase.php +++ b/lib/Cake/TestSuite/CakeTestCase.php @@ -722,13 +722,23 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase { list($plugin, $name) = pluginSplit($model, true); App::uses($name, $plugin . 'Model'); + $config = array_merge((array)$config, array('name' => $name)); + unset($config['ds']); if (!class_exists($name)) { throw new MissingModelException(array($model)); } - $mock = $this->getMock($name, $methods, array($config)); + + $availableDs = array_keys(ConnectionManager::enumConnectionObjects()); + if ($mock->useDbConfig === 'default') { + $mock->setDataSource('test'); + } + if ($mock->useDbConfig !== 'test' && in_array('test_' . $mock->useDbConfig, $availableDs)) { + $mock->setDataSource('test_' . $mock->useDbConfig); + } + ClassRegistry::removeObject($name); ClassRegistry::addObject($name, $mock); return $mock;