【问题标题】:Write tests for an angular REST app为 Angular REST 应用程序编写测试
【发布时间】:2015-04-09 13:28:36
【问题描述】:

到目前为止,我一直一无所知。假设我有这个非常简单的应用模块:

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

app.service('searchService',  ['$http', function($http){
    var baseURL="https://someonehost.com/product/search&query=";
    return  {
        search: function(query){
            return  $http.get(baseURL+query);
        }
    };
}]);

app.controller('mainCtrl', ['$scope','searchService',function($scope, searchService) {
  searchService.search($scope.searchWords).success(function(data) {
        $scope.responseData=data;
  });   
}]);

它适用于浏览器。现在我尝试使用 karma、mocha 和 chai 对其进行测试。假设我想写一个测试用例来测试请求的成功路径。我该怎么写?这是我目前正在尝试的:

describe('',function(){
    var $httpBackend = null;
    var locationService = null;
    var baseURL="https://someonehost.com/product/search&query=";

    beforeEach(function(){
        module('myApp');
        inject(function(_$httpBackend_,_locationService_){
            $httpBackend    =   _$httpBackend_;
            locationService =   _locationService_;
        });
    });

    it('test case 1',function(){
        var searchWord = 'car';
        $httpBackend.when('GET',baseURL+searchWord).respond(200,'');
        $httpBackend.expectGET(baseURL+searchWord);
        searchService.search(searchWord).success(function(data) {
          console.log('data: '+data);
        });
        $httpBackend.flush();
    });

});

但它没有返回任何数据,它应该在控制台中返回:

LOG: 'data: '
Firefox 37.0.0 (Ubuntu): Executed 1 of 1 SUCCESS (0.033 secs / 0.006 secs)

【问题讨论】:

  • 该错误表明呼叫应该是 'car' 而不是 'myhost.com/product/search ... &query=car' 这就是正在发生的事情。我认为问题出在你的测试上。
  • 是的,我知道,但我不知道如何为这个案例编写一个合适的测试用例,因为我没有这方面的经验/知识

标签: angularjs unit-testing karma-runner mocha.js chai


【解决方案1】:

默认情况下,Angular 在单元测试期间不接受外部服务的 $http。您应该为伪造数据提供模拟,并且只测试代码的完整性。

您尝试做的不是单元测试,而是集成测试,几周前我遇到了完全相同的问题。我发现这个文件覆盖了 ngMocks 并执行了正常的查询。

https://gist.github.com/kyro38/3371aaac54bf6583852f

在您的 Karma/Mocha/WhatEver 测试配置中,您在 angular 之后导入它(下面的示例适用于 Karma):

// Karma configuration
module.exports = function (config) {
config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: './',

    // frameworks to use
    // some available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine', 'chai'],

    // list of files / patterns to load in the browser
    files: [
        './bower_components/jquery/dist/jquery.js',
        './bower_components/angular/angular.js',
        './src/client/test-helpers/angular-mocks-with-real-backend.js', [...]

然后您可以根据需要运行测试。如果有任何问题,请告诉我。

别忘了让你的测试异步;)

https://jasmine.github.io/edge/introduction.html#section-Asynchronous_Support

小心$httpBackend

如文档中所述:

适用于单元测试的假 HTTP 后端实现 使用 $http 服务的应用程序。

尝试改用 $http。

it('should get nok 8 one single contact', function(done) {
    var promise = $http({
        method: 'get',
        url: baseurl + '/contact/list',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Accept': '*/*'
        },
        params: {
            nokid: 8
        }
    });
    promise.then(function(result) {
        expect(result.status).toEqual(200);
    }, function(error) {
        expect(error.status).toEqual(200);
    }).
    finally(done);
});

https://docs.angularjs.org/api/ngMock/service/$httpBackend#!

最后的提示:在你当前的测试中,你给了一个错误的 url 来期望GET:

var searchWord = 'car';
$httpBackend.expectGET(searchWord);

我会试试这个

it('test case 1',function(done){
    $http({
        method: 'get',
        url: baseURL + 'car',
        ...
    }).then(function (success) {
        console.log('data: ' + success.data);
        done(); // stop test from waiting
    }, function (fail) {
        console.log('data: ' + fail);
        done(); // stop test from waiting
    });
});

【讨论】:

  • 对不起,我没有用 Jasmine,我只用 mocha & chai。
  • 我觉得这也应该对你有用。只需在 angular 之后导入 angular-mocks-with-real-backend.js 以覆盖 ngMocks,然后照常调用您的代码。
  • 是的,现在它只显示:Firefox 37.0.0 (Ubuntu) test case 1 FAILED $httpBackend.expectGET is not a function @base/dev/test/main_test.js?1bbe45463e0fe836d98e2591cb89caf32a431057:15:3 Firefox 37.0.0 (Ubuntu):执行 1 of 1 (1 FAILED) ERROR (0.028 secs / 0 secs)
  • OK 看起来很有帮助。小心你的测试,它需要是异步的,以免在启动时直接失败。看起来您仍在使用 $httpBackend ...尝试使用 $http。异步测试:jasmine.github.io/edge/…
  • 我已经根据您的需要更新了对英尺的回答。应该有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多