【问题标题】:jasmine can not mock the elasticsearch object茉莉花无法模拟弹性搜索对象
【发布时间】:2014-09-25 16:34:16
【问题描述】:

我正在使用 yoeman、grunt、angular、grunt-jasmine、karma、elasticsearch 实现一个应用程序。我需要为我的自定义服务(名称为 elasticSearchService)编写一个测试,该服务调用 elasticsearch(elasticsearch.angular.js)来搜索某些内容并返回一个 promise,但我无法模拟该 elasticsearch(esFactory)对象。

packages.json

"karma-jasmine": "^0.1.5",
"karma-phantomjs-launcher": "^0.1.4",

bower.json

"elasticsearch": "~2.4.1",

我的服务

angular
  .module('tagsearchFrontendApp')
  .factory('elasticSearchService', ['$q', 'esFactory',
    function ($q, esFactory) {

      var client = esFactory({
        host: 'localhost:9200'
      });

      var search = function (term, offset) {
        var deferred = $q.defer();
        var query = {
          'match': {
            '_all': term
          }
        };
        client.search({
          'index': 'recipes',
          'type': 'recipe',
          'body': {
            'size': 10,
            'from': (offset || 0) * 10,
            'query': query
          }
        }).then(function (result) {
          console.log(result);
          var ii = 0,
            hits_in, hits_out = [];
          hits_in = (result.hits || {}).hits || [];
          for (; ii < hits_in.length; ii++) {
            hits_out.push(hits_in[ii]);
          }
          deferred.resolve(hits_out);
        }, deferred.reject);

        return deferred.promise;
      };
....

我的测试

describe('elasticSearchService test', function () {

  var _elasticSearchService, rootScope, q;

  beforeEach(module('tagsearchFrontendApp'));
  beforeEach(inject(['$q', '$rootScope', 'esFactory', 'elasticSearchService', function ($q, $rootScope, esFactory, elasticSearchService) {

    _elasticSearchService = elasticSearchService;
    rootScope = $rootScope;
    q = $q;

    spyOn(esFactory, "search").andCallFake(function () {
      console.log("elasticsearch: fake search");
      var deferred = $q.defer();
      deferred.resolve('The fake search resolve');
      console.log(deferred.promise);
      return deferred.promise;
    });
  }]));

  it('search okay', function () {
    _elasticSearchService.search('Developer', 1).then(function(){
       ...
    });
  });
});

执行“grunt test”后,出现错误消息“search() 方法不存在”,尽管我的应用程序使用 elasicsearch 工厂运行搜索功能正常。你能帮我解决这个错误吗?

【问题讨论】:

  • 您的意思是监视 _elasticSearchService 而不是 esFactory?你能发布确切的错误信息吗?
  • 不,我的意思是监视 esFactory,因为我的服务 (elasticSearchService) 注入 esFactory(来自 elasticsearch.angular.js)并调用它的搜索功能。错误消息是“search() 方法不存在”

标签: angularjs unit-testing elasticsearch jasmine karma-runner


【解决方案1】:

由于您创建了 esFactory 的实例,因此在原型函数中搜索功能。在您的间谍中执行以下操作

spyOn(esFactory.prototype, 'search')...

你会做生意的。

另一个观察是没有必要在你的服务中注入 q 和延迟。您可以只返回由 esFactory 客户端搜索函数创建的承诺,然后在您的处理程序中返回值而不是解析延迟。

【讨论】:

    【解决方案2】:

    您可以在配置时使用$provide 将您的服务替换为模拟服务

    describe('elasticSearchService test', function () {
    
        var esMock;
        var service;
    
        beforeEach(module('tagsearchFrontendApp') , function ($provide){
            $provide.factory('esFactory',function(){
                return function(){
                    return esMock;
                }
            });
        });
    
        beforeEach(inject(function($q,elasticSearchService){
            esMock={
               search:function(){
                return $q.when('The fake search resolve');
               }
            };
            service=elasticSearchService;
        }));
    
        it('should search with elastic search',function(){
            spyOn(esMock, 'search').andCallThrough();
            _elasticSearchService.search('Developer', 1).then(function(result){
               ...
            });
        });
    });
    

    您可能需要致电$rootScope.$apply() 来解决您的测试承诺,不确定。

    【讨论】:

    • TypeError: 'undefined' 不是一个对象(评估 'esMock')。能否请您更详细地说明一下?
    • 查看编辑。如果没有实际运行的代码,很难发现这类问题。 here 是该技术的一个工作示例
    • 感谢您的反馈,但这里有一个特殊情况:var client = esFactory({host: 'localhost:9200'});。按照您的建议修改源代码后,新的错误消息是 [object Object]' is not a function (evalating 'esFactory({host:'localhost:9200'})')。
    • 查看编辑。当然,您的模拟必须遵循与实际功能相同的接口:您的 esFactory 返回一个返回服务的函数(带有搜索功能),您的模拟必须相同。但我认为您可以自己解决这些错误!
    猜你喜欢
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多