Answers.Body: <p>Generally, you need to get a reference to the API kernel. (For testing, I usually build up a custom instance, but you can use <code>Civi::service("civi_api_kernel")</code>). Then  call <code>registerApiProvider(...)</code> and pass along a new provider. I usually define mock APIs using <code>new AdhocProvider(...)</code>.</p>
  
  <p>There are examples of mocking an API in <a href="https://github.com/civicrm/civicrm-core/blob/4.7.12/tests/phpunit/api/v3/UtilsTest.php#L364" rel="nofollow">api_v3_UtilsTest</a> and <a href="https://github.com/civicrm/civicrm-core/blob/4.7.12/tests/phpunit/CRM/Core/ManagedEntitiesTest.php#L58" rel="nofollow">CRM_Core_ManagedEntitiesTest</a>.</p>
  
  <p>(<strong>Update</strong>) I originally thought <code>api_v3_UtilsTest</code> was easier to read, but maybe <code>CRM_Core_ManagedEntitiesTest</code> is easier to generalize/imitate. Note how the <code>setup()</code> registers the API provider:</p>
  
  <pre><code>$this-&gt;apiKernel = \Civi::service('civi_api_kernel');
  $this-&gt;adhocProvider = new \Civi\API\Provider\AdhocProvider(3, 'CustomSearch');
  $this-&gt;apiKernel-&gt;registerApiProvider($this-&gt;adhocProvider);
  </code></pre>
  
  <p>and how <code>testRemoveDeclaration_CleanupUnused()</code> manipulates the <code>CustomSearch.getrefcount</code> API to return different values at different times, e.g.:</p>
  
  <pre><code>// Override 'getrefcount' ==&gt; The refcount is 1
  $this-&gt;adhocProvider-&gt;addAction('getrefcount', 'access CiviCRM', function ($apiRequest) {
    return civicrm_api3_create_success(array(
      array(
        'name' =&gt; 'mock',
        'type' =&gt; 'mock',
        'count' =&gt; 1,
      ),
    ));
  });
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-11-29T10:17:23.243Z
Answers.Text: This is super useful. I've mocked the API myself before by creating a configurable wrapper service container for my code. I'm new to the `Civi` namespaced stuff, and CiviCRM's own container system, looks a good direction and will try to grok the code when I get a chance. thanks.
Answers.UserDisplayName: artfulrobot
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-10-25T17:22:36.677Z
Answers.LastActivityDate: 2016-10-27T19:33:50.787Z
Answers.LastEditDate: 2016-10-27T19:33:50.787Z
Answers.UserDisplayName: Tim Otten
Answers.Body: <p>Maybe I'm misunderstanding the question but do you mean this?
  <a href="https://wiki.civicrm.org/confluence/display/CRMDOC/Testing#Testing-PHPunittests" rel="nofollow">https://wiki.civicrm.org/confluence/display/CRMDOC/Testing#Testing-PHPunittests</a></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-10-06T17:05:26.400Z
Answers.LastActivityDate: 2016-10-06T17:05:26.400Z
Answers.UserDisplayName: Demerit
Body: <p>Suppose I want to mock the API in unit tests for my extension, can I do that? Or should I implement an interface myself that is just a wrapper around civicrm_api3, and create mocks of that interface?</p>
  
  <p>Thank you!</p>
  
  <p>johan</p>
  
  <p><strong>update:</strong> I think a part of the answer is here in the source: <a href="https://github.com/civicrm/civicrm-core/tree/master/Civi/API/Provider" rel="nofollow">https://github.com/civicrm/civicrm-core/tree/master/Civi/API/Provider</a></p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-07T01:38:57.250Z
Comments.Text: I'm not sure it could be used to mock the Civi API, but there is [`hook_civicrm_apiWrappers()`](https://wiki.civicrm.org/confluence/display/CRMDOC/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 calls `civicrm_api3()` to interact with the API. I'm interested to see how you achieve this!
Comments.UserDisplayName: Chris Burgess
Tags: <api><testing>
Title: Can I mock the CiviCRM API for unit tests?
ThreadText: # Can I mock the CiviCRM API for unit tests?
  
  (Asked by: username_0 on 2016-10-06)
  
  Suppose I want to mock the API in unit tests for my extension, can I do that? Or should I implement an interface myself that is just a wrapper around civicrm\_api3, and create mocks of that interface?
  
  Thank you!
  
  johan
  
  **update:** I think a part of the answer is here in the source: <https://github.com/civicrm/civicrm-core/tree/master/Civi/API/Provider>
  
  **Tags:** api, testing
  
  > **Comments:**
  > **username_1**: I'm not sure it could be used to mock the Civi API, but there is [`hook_civicrm_apiWrappers()`](https://wiki.civicrm.org/confluence/display/CRMDOC/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 calls `civicrm_api3()` to interact with the API. I'm interested to see how you achieve this!  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2016-10-25. Score: 2 | Accepted answer
  
  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](https://github.com/civicrm/civicrm-core/blob/4.7.12/tests/phpunit/api/v3/UtilsTest.php#L364) and [CRM\_Core\_ManagedEntitiesTest](https://github.com/civicrm/civicrm-core/blob/4.7.12/tests/phpunit/CRM/Core/ManagedEntitiesTest.php#L58).
  
  (**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,
      ),
    ));
  });
  
  ```
  
  > **Comments:**
  > **username_3**: This is super useful. I've mocked the API myself before by creating a configurable wrapper service container for my code. I'm new to the `Civi` namespaced stuff, and CiviCRM's own container system, looks a good direction and will try to grok the code when I get a chance. thanks.  
  
  ---
  
  ### Answer by username_4 on 2016-10-06. Score: 0
  
  Maybe I'm misunderstanding the question but do you mean this?
  <https://wiki.civicrm.org/confluence/display/CRMDOC/Testing#Testing-PHPunittests>
  
  
  ---
  
  