繁体   English   中英

角度单元测试“时钟”指令的$ interval

[英]Angular unit testing $interval for a “clock” directive

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

我可以问两个答案:

  • 如果$interval点火,我如何进行单元测试?
  • 为什么$interval.flush似乎没有推进Date()

我正在遵循这些帖子的指导原则:

一篇相关文章建议使用Jasmine模拟,我认为这是不再需要的。

一个类似的问题:

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知道它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM