Generally, you need to get a reference to the API kernel. (For testing, I usually build up a custom instance, but you can use Civi::service("civi_api_kernel")
). Then call registerApiProvider(...)
and pass along a new provider. I usually define mock APIs using new AdhocProvider(...)
.
There are examples of mocking an API in api_v3_UtilsTest and CRM_Core_ManagedEntitiesTest.
(Update) I originally thought api_v3_UtilsTest
was easier to read, but maybe CRM_Core_ManagedEntitiesTest
is easier to generalize/imitate. Note how the setup()
registers the API provider:
$this->apiKernel = \Civi::service('civi_api_kernel');
$this->adhocProvider = new \Civi\API\Provider\AdhocProvider(3, 'CustomSearch');
$this->apiKernel->registerApiProvider($this->adhocProvider);
and how testRemoveDeclaration_CleanupUnused()
manipulates the CustomSearch.getrefcount
API to return different values at different times, e.g.:
// Override 'getrefcount' ==> The refcount is 1
$this->adhocProvider->addAction('getrefcount', 'access CiviCRM', function ($apiRequest) {
return civicrm_api3_create_success(array(
array(
'name' => 'mock',
'type' => 'mock',
'count' => 1,
),
));
});
hook_civicrm_apiWrappers()
. Whether it "wraps" each API request or the API itself is unclear to me. I'd think your extension would have to instantiate an API object to make it mockable? Where most CiviCRM code callscivicrm_api3()
to interact with the API. I'm interested to see how you achieve this!