11

以下のコードは実行されますが、element.popover が呼び出されないというエラーが表示されます。問題が何であるかを理解できないようです。

事前に助けてくれてありがとう。

指令:

angular.module('directives', []).

directive('popOver', function ($http) {

    return {
        restrict:'C',

        link: function (scope, element, attr) {
            element.bind('mouseover', function (e) {
                $http.get("someurl" + attr.chatid + ".json").success(function (data) {
                    element.popover({content: data.firstName + " " + data.lastName });
                });
            });
        }
    }
})

ジャスミンテスト:

'user strict'

describe('directives', function() {
    beforeEach(module('directives'));
    describe('popOver', function() {
    var $scope, compile, location,  $httpBackend, elm;

    beforeEach(inject(function($rootScope, $compile, _$httpBackend_) {
        $scope = $rootScope.$new();
        compile = $compile;
        $httpBackend = _$httpBackend_;
        elm = angular.element('<i class="pop-over" data-placement="top" data-chatid="testChatId" > </i>');
        compile(elm)($scope);

    }));

    it('should call element.popover()', function() {
        $httpBackend.expectGET('someurl/testChatId.json').
            respond([ {firstName: 'test', lastName: 'user'}]);

        spyOn(elm, 'popover').andCallThrough();

        elm.trigger('mouseover');
        $httpBackend.flush();

        expect(elm.popover).toHaveBeenCalled();
    });
  });
});

出力:

Chrome 26.0 (Mac) directives popOver should call element.popover() FAILED
Expected spy popover to have been called.
Error: Expected spy popover to have been called.
4

2 に答える 2

8

アップデート:

あなたの特定の問題を解決できませんでした。ほとんどの場合、angular-seed を実行できなかった/永遠にかかっていたためですが、答えをより完全なものにしたいと思いました。

一般に、この問題を解決するには 2 つの方法があります。

  1. イベント/仲介によってトリガーされた機能以外の機能をスパイする
  2. オブジェクトが作成される前に、関数のプロトタイプをスパイします。言い換えると:spyOn(MyObjectNamespace.Class.prototype, 'functionToSpyOn')

その後、復元するだけで問題ありません。


私はAngularに漠然としか慣れていませんが、同様の問題を経験しています。

解決策 1

関数を匿名で指定するのではなく、単に分離することができます。これは、機能を具体的にテストし、すべての角度のあるものを回避するのに役立ちます。

解決策 2

フレームワークでは、これが不可能な場合があります。ここでの主な問題は、スパイのアタッチが遅すぎて、参照が失われたり上書きされたりすることです。

テスト:

describe('directives', function() {
    beforeEach(module('directives'));
    describe('popOver', function() {
    var $scope, compile, location,  $httpBackend, elm;

    beforeEach(inject(function($rootScope, $compile, _$httpBackend_) {
        $scope = $rootScope.$new();
        compile = $compile;
        $httpBackend = _$httpBackend_;
        elm = angular.element('<i class="pop-over" data-placement="top" data-chatid="testChatId" > </i>');
        compile(elm)($scope);

    }));

    it('should call element.popover()', function() {
        var popoverFunction = $.fn.popover;
        $httpBackend.expectGET('someurl/testChatId.json').
            respond([ {firstName: 'test', lastName: 'user'}]);

        spyOn($.fn, 'popover').andCallThrough();

        elm.trigger('mouseover');
        $httpBackend.flush();

        expect($.fn.popover).toHaveBeenCalled();
        //restore popover, use sinon's restore fn instead here
        $.fn.popover = popoverFunction
    });
  });
});

ジャスミンでシノンを使用できます。Sinon には、最初と最後の行を削除する spy.restore 関数があります。私自身のテストでは、最初の行とスパイの作成を beforeEach に配置し、復元を afterEach に配置しました。

于 2013-04-09T20:38:38.857 に答える
5

私はそれを働かせました。
jquery および jquery popover js ファイルは、テスト中に angular.js の前にロードする必要があります。この順序は、testacular.conf.js ファイルで指定する必要があります。また、http の URL に「/」がありませんでした。これが私のために働いているコードです:


angular.module('directives', []).

directive('popOver', function($http) {

  return {
    restrict: 'C',

    link: function(scope, element, attr) {
      element.bind('mouseover', function(e) {
        $http.get("someurl/" + attr.chatid + ".json").success(function(data) {
          element.popover({
            content: data.firstName + " " + data.lastName
          });
        });
      });
    }
  }
})



'user strict'

describe('directives', function() {
  beforeEach(module('directives'));
  describe('popOver', function() {
    var $scope, compile, location, $httpBackend, elm;

    beforeEach(inject(function($rootScope, $compile, _$httpBackend_) {
      $scope = $rootScope.$new();
      compile = $compile;
      $httpBackend = _$httpBackend_;
      elm = angular.element('<i class="pop-over" data-placement="top" data-chatid="testChatId" > </i>');
      compile(elm)($scope);

    }));

    it('should call element.popover()', function() {
      $httpBackend.expectGET('someurl/testChatId.json').
      respond([{
        firstName: 'test',
        lastName: 'user'
      }]);
      //spyOn(elm, 'popover').andCallThrough();
      spyOn($.fn, 'popover').andCallThrough();

      elm.trigger('mouseover');
      $httpBackend.flush();

      //expect(elm.popover).toHaveBeenCalled();
      expect($.fn.popover).toHaveBeenCalled();
    });
  });
});
于 2013-04-19T15:32:26.137 に答える