Mocking dates in AngularJS / Jasmine tests

后端 未结 4 1356
一个人的身影
一个人的身影 2021-02-05 01:19

I have a directive that initializes the Date object several times in several functions. When Unit testing the individual functions I can handle stubbing the date like this:

相关标签:
4条回答
  • 2021-02-05 01:52

    angular.mock.TzDate would a better native alternative here. this comes as a helper from angular mocks and truly safe guard your test from the system timezone or any other dependencies

    https://docs.angularjs.org/api/ngMock/type/angular.mock.TzDate

    this plays well with Jasmine or mocha

    0 讨论(0)
  • 2021-02-05 01:57

    I was able to mock using a combination of sinon's fake timers to mock the window's timers and angular's mock interval service for angular to recognize time changes . Here, the countDownService under test makes use internally of both javscript Date and angular's normal interval service Something like:

      describe('when start time was 3000 milliseconds and 1001 milliseconds have passed', function() {
        var startTime;
        var elapse;
        beforeEach(function(){
          this.clock = sinon.useFakeTimers();
          startTime = 3000;
          elapse = 1001;
        });
    
        var elapseMillis = function(intervalMock,sinonClock,millis){
          sinonClock.tick(millis);
          intervalMock.flush(millis);
        };
    
        it('elapsedMillis + timeRemainingMillis should == startime', 
          inject(function($rootScope,$interval,countdownService) {
            countdownService.startTimer(startTime);
            elapseMillis($interval,this.clock,elapse);
            //jasmine clock does not mock Date
            //see https://github.com/pivotal/jasmine/issues/361
            var elapsedMillis = countdownService.getElapsedMillis();
            var timeRemainingMillis = countdownService.getTimeRemainingMillis();
            expect(elapsedMillis + timeRemainingMillis).toEqual(startTime);
            expect(elapsedMillis).toEqual(elapse);
        }));
    
        afterEach(function(){
          this.clock.restore();
            startTime = 0;
            elapse = 0;
        });
      });
    

    You'll want to make sure and include sinon js's sinon-timers-1.8.1.js in your karma.conf.js files property, too.

    0 讨论(0)
  • 2021-02-05 02:01

    Jasmine (2.2) Clock can mock dates and time.

    http://jasmine.github.io/2.2/introduction.html#section-Mocking_the_Date

    For example (from the docs):

    it("mocks the Date object and sets it to a given time", function() {
      var baseTime = new Date(2013, 9, 23);
      jasmine.clock().mockDate(baseTime);
    
      jasmine.clock().tick(50);
      expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);
    });
    
    0 讨论(0)
  • 2021-02-05 02:02

    A straightforward solution would be to create an Angular Dates service that provides Date objects for you - it might even just have a single method - Dates.now() - that just sends back the current date by returning new Date(). You then use this service whenever something needs to get the current date.

    This then allows you to inject a different Dates service when unit testing, for example one that always returns a specific date of your choice when called, rather than the current time.

    0 讨论(0)
提交回复
热议问题