wardbell / bardjs

Spec helpers for testing angular v.1.x apps with Mocha, Jasmine and QUnit
MIT License
178 stars 34 forks source link

Mocking a Data Service #27

Closed realph closed 8 years ago

realph commented 8 years ago

I'm doing unit testing for the first time and I'm trying to work out how to mock a data call from a service so I can test if the data is coming back in the correct form:

My Service

angular.module('app.core')
   .factory('PeopleService', PeopleService)

  function PeopleService($http, $q, $filter) {

    var endpoint;
    var service = {
      customers: {
        value: null
      },
      getAllCustomers: getAllCustomers,
    };

    return service;

    function getCustomers(endpoint_) {
      endpoint = endpoint_;
      service.customers.value = [];

      return handleFetch($http.get(endpoint));
    }

    function handleFetch(promise) {
      return promise.then(function (resp) {
        service.customers.value = service.customers.value.concat(resp.data.data);
      });
    }

    function getAllCustomers() {
      return $q.all([
        getCustomers('/api/customers'),
      ]).then(function(responses) {
        return responses[0];
      });
    }
  }

My Controller

angular.module('app.people')
    .controller('peopleCtrl', peopleCtrl);

function peopleCtrl($scope, PeopleService) {
    $scope.customers = PeopleService.customers;

    getCustomers();

    function getCustomers() {
      return PeopleService.getAllCustomers().then(function () {
        return PeopleService.customers.value;
      });
    }
}

My Test

describe('People Service', function () {
    var controller;
    var customers = mockData.getMockCustomers(); // my fake customers array

    beforeEach(function() {
      bard.appModule('app');
      bard.inject('$controller', '$q', '$rootScope', 'PeopleService');

      var ps = {
        getAllCustomers: function() {
          return $q.when(customers);
        }
      };

      controller = $controller('peopleCtrl', {
        $scope: $rootScope,
        PeopleService: ps
      });
    });

    it('should return an array of 5 customers', function() {
      $rootScope.$apply();
      expect($rootScope.customers).to.have.length(5);
    });
});

I've got a controller set up that when loaded talks to the People Service and gets my customers and saves the array of customers to PeopleService.customers.value. Inside my controller, I have a variable $scope.customers which is equal to PeopleService.customers.

I'm trying to mock this with my test, without hitting the API, I'm using some mock data to do this (an array of 5 customers), but not sure if I understand correctly.

Is the idea to have my mock people service return exactly what the actual people service returns? I'm kind of confused at this point. I basically want that test to check if the mock data length is equal to five.

Any help with this is appreciated. Thanks in advance!