【问题标题】:How can I test $rootScope.$emit event?如何测试 $rootScope.$emit 事件?
【发布时间】:2017-03-31 08:14:19
【问题描述】:

我在abc 控制器中有以下代码:

   $rootScope.$on('selectedItem', function (event, data) {
       vm.selectedItem = data;
   });

而调用者函数在xyz控制器中:

  function doThis(){
     $rootScope.$emit('selectedItem', 'somedata');
  }

如何在业力测试中重现或模拟此场景?

【问题讨论】:

    标签: javascript angularjs unit-testing karma-jasmine


    【解决方案1】:

    对于第一个控制器 (abc),您可以使用$rootScope.$on 收听它,您可以先使用$rootScope.$emit 它和$scope.$digest() 它。以便您可以在$on 收到它。

    var rootScope;
    beforeEach(inject(function(_$rootScope_) {
        rootScope = _$rootScope_;
    }));
    
    describe("some function", function() {
        it("should receive selectedItem with $on", function() {
            rootScope.$emit('selectedItem', 'somedata');
            $scope.$digest();
            expect(vm.selectedItem).toEqual('somedata');
        });
    });
    

    对于第二个控制器 (xyz),您可以在 $rootScope.$emit 上使用 spy。而expect 将在xyz 控制器中调用。像这样:

    var rootScope;
    beforeEach(inject(function(_$rootScope_) {
        rootScope = _$rootScope_;
        spyOn(rootScope, '$emit');
    }));
    
    describe("doThis function", function() {
        it("should $emit selectedItem", function() {
            vm.doThis(); // or if you use $scope, call it that way
            expect(rootScope.$emit).toHaveBeenCalledWith('selectedItem');
        });
    });
    

    【讨论】:

    • 无需窥探$emit 函数。您已经测试了副作用:expect(vm.selectedItem).toEqual('somedata');,这就足够了。
    • 您甚至可以删除对$injector 的需求,并替换为_$rootScope_。代码会更干净。 beforeEach((inject(function(_$rootScope_)) ..
    • @Mik378 没错,_$rootScope_ 更干净
    • 是的,但是现在您可以删除$injector 参数,您将得到一个很棒的代码:)。此外,避免与测试标签中的技术概念相关联是一种很好的做法。 '应该收到 selectedItem' 就足够了。
    • 知道了,有一个不受欢迎的间谍。那是罪魁祸首,从 abc 控制器中删除了这个:spyOn($rootScope, '$emit');。一切正常,非常感谢
    【解决方案2】:

    使用 Jasmine,它可能看起来像这样:

    var rootScope;
    beforeEach(inject(function($injector) {
        rootScope = $injector.get('$rootScope');
        spyOn(rootScope, '$emit');
    }));
    
    describe("$rootScope event testing", function() {
        it("should $emit selectedItem", function() {
            expect(rootScope.$emit).toHaveBeenCalledWith('selectedItem');
        });
    });
    

    【讨论】:

    • Expected spy $emit to have been called with [ 'selectedItem' ] but it was never called。同样在我的 beforeEach 功能块上,还有一个间谍声明,例如:spyOn($rootScope, '$emit').and.callThrough();。我应该同时添加这个 spyOn 吗?
    • 它抛出了错误:已经有一个间谍调用了发射,因此被删除并测试。但我仍然得到错误:Expected spy $emit to have been called with [ 'selectedItem' ] but it was never called
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多