I have a component whose sole function is to save data to the database and recall it consistently. However, the tests that I'm writing for the component are failing to save new records. I assume this is probably because I need to mock the table somehow, but just adding the fixtures isn't cutting it. What am I missing? Here is my component:
<?php
declare(strict_types=1);
namespace Visualize\Controller\Component;
use Cake\Controller\Component;
use Cake\Log\Log;
use Cake\ORM\TableRegistry;
/**
* Options component
*/
class OptionsComponent extends Component
{
/**
* Default configuration.
*
* @var array<string, mixed>
*/
protected $_defaultConfig = [
'model' => null,
'option_key' => null,
];
/**
* @var \Cake\ORM\Table
*/
private $Options;
/**
* @var string
*/
private $Model;
/**
* @var string
*/
private $OptionKey;
/**
* @param array $config Our configuration options
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
$this->Options = TableRegistry::getTableLocator()->get('Options');
if (!isset($config['model']) || !isset($config['option_key'])) {
die('Please configure the Options component before proceeding.');
}
$this->Model = $config['model'];
$this->OptionKey = $config['option_key'];
}
/**
* Save associated option data from a form.
*
* @param array $data HTTP data payload.
* @param int $object_id The newly created line item ID.
* @return bool
* @throws \Exception
*/
public function saveOptionsForm(array $data, int $object_id): bool
{
if (!empty($data[$this->OptionKey])) {
foreach ($data[$this->OptionKey] as $key => $value) {
$this->saveOption($object_id, $key, $value);
}
}
return true;
}
/**
* @param int $id The option key to save
* @param string $key The option value to save
* @param mixed $value The model of the associated object
* @param mixed|null $model The ID of the associated object.
* @return bool
*/
public function saveOption(int $id, string $key, mixed $value, mixed $model = null): bool
{
$option = $this->Options->newEmptyEntity();
$option
->set('object_id', $id)
->set('object_model', $model ?? $this->Model)
->set('option_name', $key)
->set('option_value', $value);
if (!$this->Options->save($option)) {
Log::error('Unable to save option:' . print_r($option, true));
return false;
}
return true;
}
}
And here is my test code:
<?php
declare(strict_types=1);
namespace Visualize\Test\TestCase\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Cake\TestSuite\TestCase;
use Visualize\Controller\Component\OptionsComponent;
/**
* Visualize\Controller\Component\OptionsComponent Test Case
*/
class OptionsComponentTest extends TestCase
{
/**
* Fixtures
*
* @var array<string>
*/
protected $fixtures = [
'app.Options',
];
/**
* Test subject
*
* @var \Visualize\Controller\Component\OptionsComponent
*/
protected $Options;
/**
* setUp method
*
* @return void
*/
protected function setUp(): void
{
parent::setUp();
$registry = new ComponentRegistry();
$this->Options = new OptionsComponent($registry, [
'model' => 'CartLines',
'option_key' => 'cart_line_options',
]);
}
public function testSaveOption(): void
{
$this->assertTrue($this->Options->saveOption(
1,
'option_1',
'value_1',
), 'Failed to save option.');
}
/**
* tearDown method
*
* @return void
*/
protected function tearDown(): void
{
unset($this->Options);
parent::tearDown();
}
}