对于“时钟”指令,角单元测试$ interval

我有一个Angular指令“时钟”, 我正在尝试编写一个单元测试,以查看时钟实际上是$ interval是否前进到未来时间 (例如,通过查看element.text() ):2分钟)。 我有一个通过当前时间的测试,现在我想测试它是否会通过$interval.flush显示未来时间。 在我看来, $interval.flush并没有真正推进时钟。

我可以要求两个答案:

  • 如果$interval触发,我如何进行单元测试?
  • 为什么$interval.flush似乎没有提前Date()
  • 我遵循这些帖子的指导原则:

  • 如何在karma angularjs中单元测试setInterval

  • http://www.bradoncode.com/blog/2015/06/15/unit-testing-interval-angularls/

  • 一个相关的帖子建议使用茉莉花嘲笑,我不认为这是必要了。

  • 在PhantomJS中使用Jasmine测试$ interval
  • 类似的问题:

  • https://groups.google.com/forum/#!topic/angular/5TFvCa5m8n0
  • HTML

      <mydatething format="EEEE, MMMM d" interval="1000" timezone="notused"></mydatething>
    

    指示

    myApp.directive('mydatething', ['$interval', 'dateFilter', function ($interval, dateFilter) {
      return {
        restrict: "AE",
        scope: {
          format: '@',
          interval: '@'
        },
        template: '', // the template is the Date() output
        link: function (scope, element, attrs) {
    
          // scope expects format, interval and timezone
          var clockid;
          var clockinterval = scope.interval;
          var dateformat = scope.format;
          var clocktimezone = scope.timezone;
    
          // DOM update function
          function updateClock() {
            element.text(dateFilter(new Date(), dateformat));
          }
    
          // Instantiate clock
          updateClock();
          clockid = $interval(updateClock, clockinterval); // fixed
    
          // For cancelling 
          scope.$on('$destroy', function () {
            $interval.cancel(clockid);
          });
    
          // Separate listener for locale change, manually refresh clock format
          scope.$on('$localeChangeSuccess', function () {
            updateClock();
          })
        }
      };
    }]);
    

    单元测试

    describe("tsdate directive", function(){
      var elem, scope, $interval, dateFilter;
        beforeEach(module('tsApp'));
        beforeEach(inject(function(_$rootScope_, _$interval_, _$compile_, _dateFilter_){
        $compile = _$compile_;
        dateFilter = _dateFilter_;
        $interval = _$interval_;
        $rootScope = _$rootScope_;
        scope = $rootScope.$new();
    
        elem = angular.element('<mydatething format="h:mm a" interval="15000"></mydatething>');
        elem = $compile(elem)(scope);
        scope.$digest();
    
        }));
        describe('on clock start', function() {
        it('to show the current date', function() {
          var currentdate = dateFilter(new Date(), elem.isolateScope().format);
          expect(elem.text()).toBe(currentdate);
          // this passes
        });
        it('that it updates the clock', function() {
          var futurems = 120000; // 2 minutes
          var futuredate = dateFilter(new Date().getTime() + futurems, elem.isolateScope().format)
          $interval.flush(futurems);
          expect(elem.text()).toBe(futuredate);
         // this fails
        });
        });
    
    });
    

    终奌站

    PhantomJS 1.9.8 (Mac OS X) mydatething directive on clock start that it updates the clock FAILED
        Expected '3:55' to be '3:57'.
    

    Console.log显示, futuredate var增加2分钟,但elem.text()保持当前时间。


    注意开始之前:

    您的指令代码中有错误。 调用$ interval时,您将函数对象作为第一个参数传递。 没有括号。

    // Do this
    clockid = $interval(updateClock, clockinterval);
    
    // Not this
    clockid = $interval(updateClock(), clockinterval);
    

    查看plunker上的差异

    其次,调用$ interval.flush会导致间隔向前移动毫秒数,但它对内部Javascript时钟没有影响。 由于您使用Date来更新时钟上的时间,因此您总是得到当前时间。 调用$ interval.flush可能会导致时间间隔更新多次,但它始终将其设置为当前时间。


    我认为你可能需要在$ interval之后使用$scope.$apply()来确保Angular知道它。

    链接地址: http://www.djcxy.com/p/87461.html

    上一篇: Angular unit testing $interval for a "clock" directive

    下一篇: Displaying and linking Foreign Key content in PHP