Add developer documentation regarding unit tests with KFC
Closed this issue · 0 comments
- KFC includes a feature to make sure that it only updates the cache for any unique record once per request.
- An entire unit test case is considered "one request".
- A developer might want to create tests that check their cache key updates when they trigger a change on that record.
Below is an example of a reasonable test that a developer might want to undertake. You would expect that the LastEdited
and getCacheKey()
values update with each var_dump()
.
class SiteConfigTest extends SapphireTest
{
protected $usesDatabase = true;
public function testSiteConfigCacheKey(): void
{
$siteConfig = SiteConfig::current_site_config();
var_dump($siteConfig->LastEdited);
var_dump($siteConfig->getCacheKey());
// Sleep for a second to make sure our date changes
sleep(1);
// Make a change to SiteConfig
$siteConfig->Title = 'Updated Site Title 1';
$siteConfig->write();
var_dump($siteConfig->LastEdited);
var_dump($siteConfig->getCacheKey());
// Sleep for a second to make sure our date changes
sleep(1);
// Make a change to SiteConfig
$siteConfig->Title = 'Updated Site Title 2';
$siteConfig->write();
var_dump($siteConfig->LastEdited);
var_dump($siteConfig->getCacheKey());
}
}
Actual: LastEdited
does update, but getCacheKey()
does not.
In order to get the expected outcome, developers need to add ProcessedUpdatesService::singleton()->flush();
before they write()
their record. This clears the cache for KFC, and will mean that any records saved will now have their cache key updated (even if they have done so previously in this request).
EG:
class SiteConfigTest extends SapphireTest
{
protected $usesDatabase = true;
public function testSiteConfigCacheKey(): void
{
$siteConfig = SiteConfig::current_site_config();
var_dump($siteConfig->LastEdited);
var_dump($siteConfig->getCacheKey());
// Sleep for a second to make sure our date changes
sleep(1);
// Flush updates from KFC so that new writes invalidate cache keys
ProcessedUpdatesService::singleton()->flush();
// Make a change to SiteConfig
$siteConfig->Title = 'Updated Site Title 1';
$siteConfig->write();
var_dump($siteConfig->LastEdited);
var_dump($siteConfig->getCacheKey());
// Sleep for a second to make sure our date changes
sleep(1);
// Flush updates from KFC so that new writes invalidate cache keys
ProcessedUpdatesService::singleton()->flush();
// Make a change to SiteConfig
$siteConfig->Title = 'Updated Site Title 2';
$siteConfig->write();
var_dump($siteConfig->LastEdited);
var_dump($siteConfig->getCacheKey());
}
}
Reconsider how we cache updated records?
It's possible as well that we should reconsider how we cache what records have been updated, so that devs don't even ever have this issue.
Off the top of my head, perhaps we could use onAfter
hooks in our Extension to perform a flush()
on ProcessedUpdatesService