如何从服务的方法模拟和测试promise的输出值?

时间:2016-11-09 00:30:03

标签: javascript angularjs unit-testing jasmine angular-promise

最简单的方法是通过实例来测试这个:

JSFiddle

问题: 使用模拟数据,我如何正确测试PromiseService.getAllData方法的输出,以使输出等于EXPECTED_OUTPUT_DATA

  [
    {email:'matthew@gmail.com', id: 10},
    {email:'matthew@gmail.com', id: 13}
  ]

MODULE + CTRL / SERVICE:

var myApp = angular.module('myApp', []);

myApp.controller('MainCtrl', MainCtrl);
myApp.service('PromiseService', PromiseService);

function MainCtrl(PromiseService) {
    console.log(PromiseService.getAllData);
}


function PromiseService($http, $q) {
    const tasks = ['/echo/json', '/echo/json'];

    const uniqueByID_ = a => {
        const map = new Map(a.map(o => [o.status, o]));
        return [...map.values()];
    };

    function getAllData() {
        // this get request is sans a real endpoint.
        return $q.all(tasks.map(req => $http.get(req)))
            .then((a) => console.log(uniqueByID_(a)));
    }

    return {
        getAllData: getAllData()
    }
}

JASMINE TEST:

describe('myApp', function() {
    let MOCK_DATA = [{
        email: 'matthew@gmail.com',
        id: 10
    }, {
        email: 'matthew@gmail.com',
        id: 10
    }, {
        email: 'matthew@gmail.com',
        id: 13
    }];

    let EXPECTED_OUTPUT_DATA = [{
        email: 'matthew@gmail.com',
        id: 10
    }, {
        email: 'matthew@gmail.com',
        id: 13
    }];

    beforeEach(() => {
        module('myApp');
        // how to mock the service to call
    })

    it('should return an array of unique objects by id', () => {
        // expect service.getAllData() to output EXPECTED_OUTPUT_DATA;
        expect().toEqual(EXPECTED_OUTPUT_DATA);
        // output would be:
        //  [
        //    {email:'matthew@gmail.com', id: 10},
        //    {email:'matthew@gmail.com', id: 13}
        //  ]
    });
});

1 个答案:

答案 0 :(得分:0)

理想情况下,您不在单元测试中测试服务,只需确保承诺解决并拒绝方法最终按照他们正在解析/拒绝的数据执行您期望的操作。以下代码可以帮助您。

var $q, PromiseService;

beforeEach(function () {
  inject(function (_$q_, _PromiseService_) {
    $q = _$q_;
    PromiseService = _PromiseService_;
  });
});

describe('activate method', function () {
  var deferred;

  beforeEach(function () {
    deferred = $q.defer();
    spyOn(PromiseService, 'getAllData').and.returnValue(deferred.promise);
  });

  it('your case', function () {
    // you can here then do
    // deferred.resolve(yourMockedData);
  });
});