title: How to mock Angular $q service in Jasmine test?
body: <p>I am trying to test an Angular service, which has 2 dependencies, one on $q and another one on 'myService' which also has dependency on $q.</p>
  
  <pre><code>(function() {
      'use strict';
  
      angular.module('myModule').factory('myService', [
          '$q',
          'apiService',
          function($q, apiService) {
  
              var data = null;
  
              function getData() {
                  var deferred = $q.defer();
  
                  if (data === null) {
  
                      apiService.get('url').then(function(result) {
                          data = result;
                          deferred.resolve(data);
                      }, function() {
                          deferred.reject();
                      });
                  } else {
                      deferred.resolve(data);
                  }
  
                  return deferred.promise;
              }
  
              return {
                  getData: getData
              };
          }
      ]);
  })();
  </code></pre>
  
  <p>I started writing a Jasmine test as seen below, but and having issues mocking $q. I would like to inject the real version of $q instead of the mock version to 'myService' and 'apiService', but am not sure how to accomplish that.</p>
  
  <pre><code>'use strict';
  
  describe('My service', function() {
      var qSpy, apiServiceSpy;
  
      beforeEach(module('myModule'));
  
      beforeEach(function() {
          qSpy = jasmine.createSpyObj('qSpy', ['defer']);
  
          apiServiceSpy = jasmine.createSpyObj('apiServiceSpy', ['get']);
          apiServiceSpy.get.and.callFake(function() {
              var deferred = $q.defer();
              deferred.resolve('Remote call result');
              return deferred.promise;
          });
  
          module(function($provide) {
              $provide.value('$q', qSpy);
              $provide.value('apiService', apiServiceSpy);
          });
      });
  
      it('should get data.', inject(function(myService) {
          // Arrange
  
          // Act
          var data = myService.getData();
  
          // Assert
          expect(data).not.toBeNull();
      }));
  });
  </code></pre>
  
  <p><strong>Edit</strong>
  Here is the updated test based on the responses below.  I guess my issue was I assumed I had to provide $q.</p>
  
  <pre><code>'use strict';
  
  describe('My service', function() {
      var service, apiServiceSpy;
  
      beforeEach(module('myModule'));
  
      beforeEach(function() {
          apiServiceSpy = jasmine.createSpyObj('apiServiceSpy', ['get']);
  
          module(function($provide) {
              $provide.value('apiService', apiServiceSpy);
          });
      });
  
      beforeEach(inject(function($q, myService) {
          service = myService;
  
          apiServiceSpy.get.and.callFake(function() {
              var deferred = $q.defer();
              deferred.resolve('Remote call result');
              return deferred.promise;
          });
      }));
  
      it('should get data.', function() {
          // Arrange
  
          // Act
          var data = service.getData();
  
          // Assert
          expect(data).not.toBeNull();
      }));
  }); 
  </code></pre>