I have the following test for my behavior in
tests\TestCase\Model\Behavior\SluggableBehaviorTest.php
The function I want to test in the behavior is
src\Model\Behavior\SluggableBehavior.php
How do I mock the query to check for duplicates, or attach a fixture to a mock table class?
Thanks.
-- tests\TestCase\Model\Behavior\SluggableBehaviorTest.php
<?php
namespace App\Test\TestCase\Model\Behavior;
use App\Model\Behavior\SluggableBehavior;
use Cake\TestSuite\TestCase;
//use ArrayObject;
use Cake\Core\Plugin;
use Cake\ORM\Entity;
use Cake\ORM\Table;
use PHPUnit_Framework_TestCase;
/**
* App\Model\Behavior\SluggableBehavior Test Case
*/
class SluggableBehaviorTest extends TestCase
{
private $config = array();
/**
* setUp method
*
* @return void
*/
public function setUp()
{
parent::setUp();
$this->config = [
'field' => 'title',
'slug' => 'slug',
'scope' => array(),
'separator' => '-',
'unique' => true,
'update' => false,
'trigger' => false
];
}
/**
* tearDown method
*
* @return void
*/
public function tearDown()
{
unset($this->Sluggable);
parent::tearDown();
}
/**
* Test initial setup
*
* @return void
*/
public function testInitialization()
{
$this->markTestIncomplete('Not implemented yet.');
}
/**
* Data provider method for testing valid file uploads
*
* @return array
*/
public function slugEntityProvider()
{
return [
[
[],
['title' => 'Test', 'slug' => ''],
['title' => 'Test', 'slug' => 'test']
],
[
['field' => 'other_title', 'slug' => 'other_slug'],
['other_title' => 'Test Name', 'other_slug' => ''],
['other_title' => 'Test Name', 'other_slug' => 'test-name']
],
[
['separator' => '_'],
['title' => 'Test Name', 'slug' => ''],
['title' => 'Test Name', 'slug' => 'test_name']
]
];
}
/**
* Test that correct field is slugged
*
* @dataProvider slugEntityProvider
*/
public function testSlug(array $configUpdates, array $entityData, array $expected)
{
$config = $this->config;
foreach($configUpdates as $key => $value) {
$config[$key] = $value;
}
$table = $this->getMock('Cake\ORM\Table', null);
$Sluggable = $this->getMockBuilder('App\Model\Behavior\SluggableBehavior')
->setConstructorArgs([$table, $config])
->setMethods(['makeUniqueSlug'])
->getMock();
$Sluggable->expects($this->once())
->method('makeUniqueSlug')
->will($this->returnValue($expected[$config['slug']]));
$entity = new Entity($entityData);
$Sluggable->slug($entity);
$this->assertEquals($expected[$config['slug']], $entity[$config['slug']]);
}
/**
* Data provider method for testing valid file uploads
*
* @return array
*/
public function beforeSaveEntityProvider()
{
return [
[
['update' => false],
['slug' => 1],
['title' => 'Test Name', 'slug' => ''],
['title' => 'Test Name', 'slug' => 'test-name']
],
[
['update' => false],
['slug' => 0],
['id' => 1, 'title' => 'Test Name', 'slug' => 'test'],
['id' => 1, 'title' => 'Test Name', 'slug' => 'test']
],
[
['update' => true],
['slug' => 1],
['id' => 1, 'title' => 'Test Name', 'slug' => 'test'],
['id' => 1, 'title' => 'Test Name', 'slug' => 'test-name']
],
[
['trigger' => false],
['slug' => 1],
['title' => 'Test Name', 'slug' => '', 'trigger' => false],
['title' => 'Test Name', 'slug' => 'test', 'trigger' => false]
],
[
['trigger' => 'use_slug'],
['slug' => 0],
['title' => 'Test Name', 'slug' => '', 'use_slug' => false],
['title' => 'Test Name', 'slug' => '', 'use_slug' => false]
]
];
}
/**
* Test that field is only slugged when config specifies
*
* @dataProvider beforeSaveEntityProvider
*/
public function testBeforeSave(array $configUpdates, array $methodCalls, array $entityData, array $expected)
{
$config = $this->config;
foreach($configUpdates as $key => $value) {
$config[$key] = $value;
}
$table = $this->getMock('Cake\ORM\Table', null);
$Sluggable = $this->getMockBuilder('App\Model\Behavior\SluggableBehavior')
->setConstructorArgs([$table, $config])
->setMethods(['slug'])
->getMock();
if ($methodCalls['slug'] == 1) {
$Sluggable->expects($this->once())
->method('slug')
->will($this->returnValue($expected[$config['slug']]));
} elseif ($methodCalls['slug'] == 0) {
$Sluggable->expects($this->never())
->method('slug')
->will($this->returnValue($expected[$config['slug']]));
}
$entity = new Entity($entityData);
$Sluggable->beforeSave($this->getMock('Cake\Event\Event', null, ['beforeSave']), $entity);
}
}
The function I want to test in the behavior is
src\Model\Behavior\SluggableBehavior.php
/**
* Generates a unique slug for that table.
*
* @param \Cake\ORM\Entity $entity the entity that is going to be saved
* @return $slug
*/
protected function _makeUniqueSlug(Entity $entity)
{
$config = $this->config();
$slug = Inflector::slug($entity->get($config['field']), $config['separator']);
if (!$config['unique']) {
return $slug;
}
$results = $this->_scope($this->_table->find())
->select(['id', $config['slug']])
->where([$config['slug'] => $slug])
->orWhere([$config['slug'] . ' REGEXP' => '^' . $slug . $config['separator'] . '[0-9]+'])
->all();
$duplicates = array();
foreach ($results as $result) {
$duplicates[] = $result->{$config['slug']};
}
if (!empty($duplicates)) {
$startSlug = $slug;
$index = 1;
while ($index > 0) {
if (!in_array($startSlug . $config['separator'] . $index, $duplicates)) {
$slug = $startSlug . $config['separator'] . $index;
$index = -1;
}
$index++;
}
}
return $slug;
}
/**
* Alters the passed query so that it only returns scoped records as defined
* in the tree configuration.
*
* @param \Cake\ORM\Query $query the Query to modify
* @return \Cake\ORM\Query
*/
protected function _scope($query)
{
$config = $this->config();
if (is_array($config['scope'])) {
return $query->where($config['scope']);
} elseif (is_callable($config['scope'])) {
return $config['scope']($query);
}
return $query;
}
How do I mock the query to check for duplicates, or attach a fixture to a mock table class?
Thanks.
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP
---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+unsubscribe@googlegroups.com.
To post to this group, send email to cake-php@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/d/optout.
No comments:
Post a Comment