使用 Jasmine 测试 angular 服务返回的 API 响应格式

Testing the API responses format returned by angular service with Jasmine

大多数问题发生在我和 API 之间的交互格式发生变化时。我想测试与 API 通信的 angular 服务。如果此服务使用 $http,我如何将我的 angular 服务注入测试并获得正确的结果?我应该使用 jasmine,这种类型的集成测试的单元测试工具吗?

在这个例子中,我正在测试使用 $http 和 returns 承诺的 OntologyService,测试看起来像这样:

describe('Service: OntologyService', function () {
    var OntologyService, $scope;
    beforeEach(function () {
        module('oneClickRegistrationApp');
        inject(function ($injector) {
            OntologyService = $injector.get('OntologyService');
            $scope = $injector.get('$rootScope').$new();
        });
    });

    it('should return the object of ontologies', inject(function () {
        var ontoServerApiUrl = 'https://myurl.com/api/ksearch/ontologies/';
        OntologyService.getAllOntologies(ontoServerApiUrl).then(function (ontologies) {
            expect(ontologies).toBeNonEmptyObject();
            expect(ontologies["licenses"]).toHaveArrayOfObjects();
            expect(ontologies["species"]).toHaveArrayOfObjects();
            expect(ontologies["measurement_methods"].length).toBeGreaterThan(10);
        });
        $scope.$digest();
    }));
});

我收到以下错误消息:

PhantomJS 1.9.8 (Mac OS X 0.0.0) Service: OntologyService should return the object of ontologies FAILED
    Error: Unexpected request: GET https://myurl.com/api/ksearch/ontologies/hbp_data_modality_ontology?size=10000
    No more request expected
        at $httpBackend (/Users/katkov/WebstormProjects/one-click/bower_components/angular-mocks/angular-mocks.js:1323)
        at sendReq (/Users/katkov/WebstormProjects/one-click/bower_components/angular/angular.js:10761)
        at /Users/katkov/WebstormProjects/one-click/bower_components/angular/angular.js:10470
        at processQueue (/Users/katkov/WebstormProjects/one-click/bower_components/angular/angular.js:14991)
        at /Users/katkov/WebstormProjects/one-click/bower_components/angular/angular.js:15007
        at /Users/katkov/WebstormProjects/one-click/bower_components/angular/angular.js:16251
        at /Users/katkov/WebstormProjects/one-click/bower_components/angular/angular.js:16069
        at /Users/katkov/WebstormProjects/one-click/test/spec/services/realontologyservice.js:32
        at invoke (/Users/katkov/WebstormProjects/one-click/bower_components/angular/angular.js:4535)
        at workFn (/Users/katkov/WebstormProjects/one-click/bower_components/angular-mocks/angular-mocks.js:2517)
    undefined
PhantomJS 1.9.8 (Mac OS X 0.0.0): Executed 9 of 9 (1 FAILED) (0.016 secs / 0.158 secs)

Error: Unexpected request: GET https://

此博客 post 为您介绍:http://www.bradoncode.com/blog/2015/06/16/unit-test-http-ngmock-passthrough/

...$httpBackend service requires us to mock all HTTP requests used in the code under test...

...it would be nice to make a real HTTP call so that I can experiment, get some example JSON etc...

...ngMock does include ngMockE2E, which allows us to create fake backend HTTP calls, but we can only use this in the full application i.e. via the browser and not from unit tests...

这里是如何制作真正的 http 请求:

describe('real http tests', function() {

  beforeEach(angular.mock.http.init);
  afterEach(angular.mock.http.reset);

  beforeEach(inject(function(_$controller_, _$httpBackend_) {
    $controller = _$controller_;
    $scope = {};
    $httpBackend = _$httpBackend_;

    // Note that this HTTP backend is ngMockE2E's, and will make a real HTTP request
    $httpBackend.whenGET('http://www.omdbapi.com/?s=terminator').passThrough();
  }));

  it('should load default movies (with real http request)', function (done) {
    var moviesController = $controller('MovieController', { $scope: $scope });

    setTimeout(function() {
      expect($scope.movies).not.toEqual([]);
      done();
    }, 1000);

  });

});