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
This commit is contained in:
mark_story 2014-10-12 22:14:47 -04:00
parent ecf030796b
commit 9b9e886df6
2 changed files with 57 additions and 9 deletions

View file

@ -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);

View file

@ -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;