简体   繁体   中英

Jasmine Mock for Angular service using promise

I have the following Angular service and mock/test setup. I cannot get the mock http request to work properly. I'm returning a promise from my factory and have the HTTP request mocked but the data in the controller's scope is not the data returned from the http service that the factory calls.

As you can see, I have called $digest() on $rootScope and $httpBackend . I'm at a loss.

You can see from the fiddle that the code works properly and displays the text from the service, but the mock is not working.

Why?

The fiddle is here: https://jsfiddle.net/mbaranski/gnxxbgy3/ Here is the code:

var myApp = angular.module('myApp', []);
var ep = '/echo/json/';
myApp.factory('dataFactory', function($http) {
  var getData = function() {
    var data = $.param({
      json: JSON.stringify({
        name: "Name from Echo Service"
      })
    });
    return $http.post(ep, data);
  }

  return {
    getData: getData
  }
});

myApp.controller('MyCtrl', function($scope, dataFactory) {
  $scope.name = 'Original Name';
  dataFactory.getData().then(function(data) {
    $scope.name = data.data.name;
  });
});

describe('Test For Site', function() {
  beforeEach(angular.mock.module('myApp'));
  var $controller;
  var $httpBackend;
  var $q;
  var $rootScope;
  beforeEach(angular.mock.inject(function(_$controller_, _$httpBackend_, _$q_, _$rootScope_) {
    $controller = _$controller_;
    $httpBackend = _$httpBackend_;
    $q = _$q_;
    $rootScope = _$rootScope_;
  }));

  describe('test pageController', function() {
    it('Should pass', function() {
      var scope = {};
      $httpBackend.expect('POST', ep);
      $httpBackend.whenPOST(ep, function(str) {
        return true;
      }).respond(
        function() {
          return {
            name: "Name from Echo Service"
          };
        });
      var controller = $controller('MyCtrl', {
        $scope: scope,
      });
      $httpBackend.flush();
      $rootScope.$digest();
      $rootScope.$flush();

      expect(scope.name).toBe('Name from Echo Service');
    });
  });
});

Here's the HTML

<div ng-controller="MyCtrl">
  Hello, {{name}}!
</div>
<br/>

I was really minute problem, which took a lot to find it. .whenPOST of $httpBackend should only return object/string & your were returning a function which was returning by from .respond of ..whenPOST method.

Just by returning plain JSON, rather than returning function solved the issue.

Code

$httpBackend.whenPOST(ep, function(str) {
    return true;
}).respond({
    name: "Name from Echo Service"
});

Also remove $rootScope.$flush(); this line. $rootScope doesn't have $flush method in it.

Forked JSFiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM