user3284007
user3284007

Reputation: 1717

Testng a partally executed $timeout in AngularJS

I have an AngularJS service. This service uses a $timeout in its function. I'm trying to figure out how to test this service in various situations. Here is my code:

myApp.factory('myService', ['$timeout', function($timeout) {
  var isRunning = false;
  var myTimer = null;

  return {
    myTimer: myTimer,
    isRunning: isRunning,

    execute: function(time) {
      this.isRunning = true;
      this.myTimer = $timeout(
        function() {
          this.isRunning= false;
          this.myTimer= null;
        },
        time
      );                
    }
  };
}]);

Now, I'm trying to test this code. I have the following written:

describe('myService', function () {
  var myService = null;
  var $timeout = null;
  var $rootScope = null;

  beforeEach(inject(function (_$timeout_, _$rootScope_, _myService_) {
    myService = _myService_;
    $timeout = _$timeout_;
    $rootScope = _$rootScope_;
  }));

  it('should run for one second', function() {
    myService.execute(1000);
    $timeout.flush();
    $rootScope.$digest();

    expect(myService.isRunning).toBe(false);
  });
});

The test "works". However, if 750 milliseonds have elapsed, I would expect myService.isRunning to be true. However, I do not know how to test for that scenario. Can someone please show me how to test tht situation? thank you

Upvotes: 2

Views: 65

Answers (1)

Chad Campbell
Chad Campbell

Reputation: 937

You can imitate a certain amount of time passing with the $timeout.flush method. The method takes an optional parameter called delay. It's explained in the documentation here. With that in mind, you could write a test that looks like this:

it('should run for one second', function() {
  myService.execute(1000);
  $timeout.flush(750);
  $rootScope.$digest();

  expect(myService.isRunning).toBe(true);
});

Upvotes: 3

Related Questions