Тестирование угловых $http внутри цепочки обещаний с мокко

У меня есть jsdom/mocha/chai, настроенный для углового тестирования бэкэнда.

У меня есть сервис, который по существу делает это (намеренно не публикует данные):

app.service('testService', ['config', '$http', function(config, $http) {
    function getSpecificConfig(type) {
        return config.getConfig()
        .then(function(config) {
            // config is coming back defined;
            // $http timesout
            return $http({method: 'post', url: 'http://localhost:2222/some/path', withCredentials: true});
        })
        .then(function(res) {
            return res.data.config[type];
        })
        .catch(function(err) {
            //handles err
        });
    };

    return {
        getConfig: getConfig
    }
}]);

мой тест:

/* jshint node: true */
/* jshint esversion: 6 */

let helpers = require(bootstrapTest),
    inject = helpers.inject,
    config,
    specificConfig,
    mockResponse,
    $httpBackend,
    $rootScope;

//config service
require('config.js');

//testService I'm testing
require('testService');

beforeEach(inject(function($injector, _$httpBackend_) {
    config = $injector.get('config');
    specificConfig = $injector.get('testService');
    $rootScope = $injector.get('$rootScope');
    $httpBackend = _$httpBackend_;

    $httpBackend.when('POST', 'http://localhost:2222/some/path')
    .response(function(data) {
        //would like this to fire
        console.log('something happened');
        mockResponse = {data: 'some data'};
        return mockResponse;
    });
}));   

afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectations();
    $httpBackend.verifyNoOutstandingRequest();
});

describe ('this service', function() {
    beforeEach(function() {
        $httpBackend.expect('POST', 'http://localhost:2222/some/path');
        $rootScope.$apply(function() {
            return specificConfig('something');
        });
    });

    it ('returns the specific config', function() {
        expect(mockResponse).to.equal('some data');
    })
});

Проблема: при запуске теста config.getConfig () разрешается правильно, но $http приводит к истечению времени ожидания mocha (2000 мс), а ловушка afterEach генерирует неудовлетворенный запрос.

Мое понимание этого может быть совершенно неверным, поэтому, пожалуйста, не стесняйтесь обучить меня правильному подходу (вот мой подход):

1) требуют все необходимые зависимости.

2) внедрить их и настроить прослушиватель $httpBackend, который запускает тестовый ответ при срабатывании реального http.

3) $ rootScope. $ Apply () любые обещания, поскольку их разрешение связано с угловым жизненным циклом.

4) первый перед каждым устанавливает слушателя, второй перед каждым запускает службу, которая запускает $http, позволяя $httpBackend запускать и устанавливать mockResponse.

5) тестовая реакция на ответ.

1 ответ

Если вам нужно возвращать обещания в ваших ложных HTTP-запросах, вы можете использовать angular-mocks-async следующим образом:

var app = ng.module( 'mockApp', [
    'ngMockE2E',
    'ngMockE2EAsync'
]);

app.run( [ '$httpBackend', '$q', function( $httpBackend, $q ) {

    $httpBackend.whenAsync(
        'GET',
        new RegExp( 'http://api.example.com/user/.+$' )
    ).respond( function( method, url, data, config ) {

        var re = /.*\/user\/(\w+)/;
        var userId = parseInt(url.replace(re, '$1'), 10);

        var response = $q.defer();

        setTimeout( function() {

            var data = {
                userId: userId
            };
            response.resolve( [ 200, "mock response", data ] );

        }, 1000 );

        return response.promise;

    });

}]);
Другие вопросы по тегам