Angularjs 如何在jasmine中使用外部依赖项对ngcontroller进行单元测试?

Angularjs 如何在jasmine中使用外部依赖项对ngcontroller进行单元测试?,angularjs,unit-testing,karma-jasmine,Angularjs,Unit Testing,Karma Jasmine,我试图为一个角度控制器写一个karma单元测试,这就是控制器。从此处使用文件上载: 我的茉莉花测试如下所示: describe('Customer: Controller: DocumentsController', function() { var $rootScope, DocumentMock, UserMock, documentsController, scope; documentsController = $rootScope = scope = DocumentMock

我试图为一个角度控制器写一个karma单元测试,这就是控制器。从此处使用文件上载:

我的茉莉花测试如下所示:

describe('Customer: Controller: DocumentsController', function() {
  var $rootScope, DocumentMock, UserMock, documentsController, scope;
  documentsController = $rootScope = scope = DocumentMock = UserMock = null;

  beforeEach(function() {
    module("mycontrollers");
    return inject(function($controller, _$rootScope_, $q) {
      var deferred, documents, fileUploader, uploadHelper, user;
      $rootScope = _$rootScope_;
      scope = $rootScope.$new();
      documents = [
        {
          id: "doc 1",
          documentType: "other"
        }, {
          id: "doc 2",
          documentType: "pdf"
        }, {
          id: "doc 3",
          v: "pdf"
        }
      ];
      user = {
        id: 'user_id',
        username: 'username'
      };
      UserMock = {
        currentUser: function() {
          return user;
        }
      };
      fileUploader = {};
      uploadHelper = {};

      return documentsController = $controller('DocumentsController', {
        documents: documents,
        $scope: scope,
        FileUploader: fileUploader,
        UploadHelper: uploadHelper,
        currentUser: UserMock

      });
    });
  });
  return describe("On creation", function() {
    return it("should assign documents to scope", function() {
      return expect(1).toEqual(1);
    });
  });
});
我得到了一个名为QuestionsAttachments的服务,它有几个依赖项:

s = function(API, $http, $q, $timeout) {
  var QuestionsAttachments;
  return QuestionsAttachments = (function() {
    function QuestionsAttachments(data) {
      angular.extend(this, data);
    }

    QuestionsAttachments["new"] = function(data) {
      return new QuestionsAttachments(data);
    };

    return QuestionsAttachments;

  })();
};

di = ['API', '$http', '$q', '$timeout', s];
问题是:如何模拟API、$http、$q、$timeout

这是指向PRUNKR的链接:

基本上你要做的就是在这种方法上设置一个间谍 服务 您所要做的就是让injetable服务成为真正的实现 而mock/stub就是您需要的函数。不需要创建自己的 类似这样的模拟对象:uploadHelper={}

你可以阅读更多关于茉莉花和特务的信息

尽管如此,我必须说提供的代码看起来确实有点不完整。 例如,通过示例,假设您没有创建模块,并且直接使用getter语法,而不是angular.module'mycontrollers',[]

第二,在您的测试中,您试图在控制器实例化期间注入文档,但这永远不会起作用,因为您的控制器定义中没有可注入参数“documents”

因此,您所经历的问题可能是由于上述概述

无论如何,一个完整的示例,重点是如何在UploadHelper.getOptions上模拟/stub/spy,可能看起来像这样。这是一个有效的弹片

实施 测验
下面是一个为注入服务创建完整模拟的简短示例

var mockInjectedProvider;

beforeEach(function() {
  module('myModule');
});

beforeEach(inject(function(_injected_) {
      mockInjectedProvider = mock(_injected_);
    });

    beforeEach(inject(function(_base_) {
      baseProvider = _base_;
    }));

    it("injectedProvider should be mocked", function() {
      mockInjectedProvider.myFunc.andReturn('testvalue');
      var resultFromMockedProvider = baseProvider.executeMyFuncFromInjected();
      expect(resultFromMockedProvider).toEqual('testvalue');
    });

    //mock all service methods
    function mock(angularServiceToMock) {

      for (var i = 0; i < Object.getOwnPropertyNames(angularServiceToMock).length; i++) {
        spyOn(angularServiceToMock, Object.getOwnPropertyNames(angularServiceToMock)[i]);
      }
      return angularServiceToMock;
    }

嗨,我稍微改变了一下,我有另一个名为questionsAttachments的服务,如上所述,你只需选择api/服务和方法,并在其上放置一个间谍。请再看看我的答案。此外,由于你犯了几个错误,plunkr无法工作。这里有一个为你工作的例子。这个plunkr是正确的一个:我不知道你的目的是什么。在您的plunkr中,您试图注入一些服务,但这并不存在。另外,在new:function{}块中,您试图创建新的问题附件,但这也不存在。您已将工厂函数命名为lekker,因此通过将其重命名为QuestionsAttactions并删除someservice的注入,您可以看到真正的问题。尽管我建议你仔细阅读。下面我给你的答案给了你几乎所有你需要的。
spyOn(uploadHelper, 'getOptions').andCallFake(function(){
    // return data here
});

// or you could use .Return({ /* some object */})
angular
    .module('mycontrollers',[])
    .controller('DocumentsController', documentsController);
    
    documentsController.$inject = ['$scope', 'FileUploader', 'UploadHelper', 'currentUser'];
    
    function documentsController($scope, FileUploader, UploadHelper, currentUser){
        var uploader;
        
        $scope.uploader = uploader = new FileUploader(UploadHelper.getOptions());
        
        uploader.onSuccessItem = function(item, response, status, headers){
            // do something
        };
    }
describe('Customer: Controller: DocumentsController', function(){
    beforeEach(function(){
        module('mycontrollers');
        
        inject(function($injector){
            // fetch our dependencies
            this.$controller = $injector.get('$controller');            
            this.FileUploader = $injector.get('FileUploader');
            this.UploadHelper = $injector.get('UploadHelper');
            this.$scope = $injector.get('$rootScope').$new();
            this.user = {
                id: 'user_id',
                username: 'username'
            };
            this.UserMock = {
                currentUser: function(){
                    return user;
                }
            }
        });
    });
    
    function initController(context){
        return context.$controller('DocumentsController', {
                $scope: context.$scope,
                FileUploader: context.FileUploader,
                UploadHelper: context.UploadHelper,
                currentUser: context.UserMock
            });
    }
    
    describe('On creation', function(){
        it('should call UploadHelper.getOptions()', function(){
            // spy on getOptions and when it is getting called, return whatever we've specified
            spyOn(this.UploadHelper, 'getOptions').andReturn({ /* some options */});
            
            // instantiate the controller
            initController(this);
            
            expect(this.UploadHelper.getOptions).toHaveBeenCalled();
            expect(this.$scope.uploader.onSuccessItem).toBeDefined();
        });
    });
});
var mockInjectedProvider;

beforeEach(function() {
  module('myModule');
});

beforeEach(inject(function(_injected_) {
      mockInjectedProvider = mock(_injected_);
    });

    beforeEach(inject(function(_base_) {
      baseProvider = _base_;
    }));

    it("injectedProvider should be mocked", function() {
      mockInjectedProvider.myFunc.andReturn('testvalue');
      var resultFromMockedProvider = baseProvider.executeMyFuncFromInjected();
      expect(resultFromMockedProvider).toEqual('testvalue');
    });

    //mock all service methods
    function mock(angularServiceToMock) {

      for (var i = 0; i < Object.getOwnPropertyNames(angularServiceToMock).length; i++) {
        spyOn(angularServiceToMock, Object.getOwnPropertyNames(angularServiceToMock)[i]);
      }
      return angularServiceToMock;
    }