Javascript 测试服务依赖于其他有承诺的服务(Karma-Angular)

Javascript 测试服务依赖于其他有承诺的服务(Karma-Angular),javascript,angularjs,promise,karma-runner,Javascript,Angularjs,Promise,Karma Runner,我有一个使用fileReader服务的解析器服务: app.factory( 'parserService', [ '$q', 'fileReader', function ( $q, fileReader ) { var parser = {}; parser.addASTtoFilesInTree = function ( fileTree ) { var promises = []; traverse(fileTree); retu

我有一个使用fileReader服务的解析器服务:

app.factory( 'parserService', [ '$q', 'fileReader', function ( $q, fileReader ) {

   var parser = {};

   parser.addASTtoFilesInTree = function ( fileTree ) {

      var promises = [];

      traverse(fileTree);

      return $q.all(promises);

   }
   return parser;

}]);
文件阅读器是:

app.factory( 'fileReader', [ '$q', function ($q) {

   var fileReader = {};

   fileReader.readFile = function( file ) {

      var defer = $q.defer();

      var reader = new FileReader();

      reader.onload = function(e) {
         defer.resolve(e.target.result);
      };

      reader.onerror = function(msg){
         console.log(msg);
         //add defer on error
      };

      reader.readAsBinaryString(file.ref);

      return defer.promise;
   };

   return fileReader;

}]);
我目前正在尝试使用karma-jasmine创建一个测试,以测试parseService中的addASTtoFilesInTree函数

describe( "parser tests" , function() {

  var parserService, $rootScope;

  var mockFileReader = {
    readFile: function( file ) {
      var defer = $q.defer();
      defer.resolve(file.ref.content);
      console.log("in mockFileReader"); // this never gets called
      return defer.promise;
    }
  };

  var mockFileContent = "..."
  var mockAST = { ... }
  var itemOne = {...};
  var parsedItemOne = { ... }        
  var mockFileTree = { ... };


  beforeEach( function() {

    //load the module
    module('FYP');

    //using mock service
    module( function($provide) {
      $provide.value = ('fileReader', mockFileReader);
    });

    //inject service for testing
    inject( function( _$rootScope_, _parserService_) {
      $rootScope = _$rootScope_;
      parserService = _parserService_;
    });
  });

  describe( "addASTtoFilesInTree", function() {

    it('should add AST to all JS file', function() {

      parserService.addASTtoFilesInTree(mockFileTree).then(function() {

                  console.log("in THEN"); //this never gets called
      });

      $rootScope.$digest();
        expect(mockFileTree['root'].files['itemOne']).toEqual(parsedItemOne);//fails since it compares the two objects before promise is returned

    });
  });
});
测试失败是因为它在承诺返回之前比较了两个对象。我错过什么了吗

尝试使用装饰器: 或者只是一种价值服务:
什么是
遍历(fileTree)?该函数遍历文件树对象,为文件树中的每个文件调用fileReader.readFile。它还为每个被读取的文件向promises数组添加了一个promise,让我们关注这个问题
console.log(fileReader)
/
console.log(Promissions)
在parserService内部,好吧,所以我做了一个
console.log(fileReader)
,看起来fileReaderMock没有取代原来的fileReader服务。谢谢,这让我发疯了。因此,您的第一个解决方案
$provide.decorator('fileReader',function(){return mockFileReader;})解决了问题。thanks@BuildingJarl很高兴帮助你
//load the module
module('FYP');

//using mock service
module( function($provide) {
  $provide.decorator('fileReader', function() {
    return mockFileReader;
  });
});

//inject service for testing
inject( function( _$rootScope_, _parserService_, _$q_ ) {
  $rootScope = _$rootScope_;
  parserService = _parserService_;
  $q = _$q_;
});
beforeEach(module('FYP'));

beforeEach(function () {

module( function($provide) {
     $provide.value('fileReader', mockFileReader);
    });
});

beforeEach(inject( function( _$rootScope_, _parserService_, _$q_) {  
  $rootScope = _$rootScope_;
  parserService = _parserService_;
  $q = _$q_;
}));