How to conditionally flush a $timeout in Angular unit test

后端 未结 2 1908
醉酒成梦
醉酒成梦 2021-01-27 16:24

I have code that is something like this:

function doThing() {
  if (invalidInput) {
    console.error(\'Invalid input.\');
    return;
  }

  $timeout(function()         


        
2条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-27 17:00

    I suggest define two separate unit tests to verify the behavior of your doThing function. Try following code:

    • Controller
    (function () {
      'use strict';
    
      angular.module('myApp', [])
        .controller('MainCtrl', function ($timeout, MyService) {
          var vm = this;
    
          vm.invalidInput = true;
          vm.doThing = doThing;
    
          function doThing() {
            if (vm.invalidInput) {
              return;
            }
    
            $timeout(function () {
              MyService.doThing();
            }, 1000);
          }
    
        });
    })();
    
    • Service
    (function () {
      'use strict';
    
      angular.module('myApp').service('MyService', MyService);
    
      function MyService() {
    
        this.doThing = function () {
          // doThing code
        };
      }
    })();
    
    • Unit test
    'use strict';
    
    describe('Controller: MainCtrl', function () {
    
      beforeEach(module('myApp'));
    
      var vm,
        $timeout,
        MyService;
    
      beforeEach(inject(function (_$controller_, _$timeout_, _MyService_) {
        $timeout = _$timeout_;
        MyService = _MyService_;
        vm = _$controller_('MainCtrl', {
          $timeout: $timeout,
          MyService: MyService
        });
      }));
    
      it('should call doThing for valid inputs', function () {
        spyOn(MyService, 'doThing').andCallThrough();
    
        vm.invalidInput = false;
        vm.doThing();
        $timeout.flush();
        expect(MyService.doThing).toHaveBeenCalled();
      });
    
      it('should not call doThing for invalid inputs', function () {
        spyOn(MyService, 'doThing').andCallThrough();
    
        vm.invalidInput = true;
        vm.doThing();
        expect(MyService.doThing).not.toHaveBeenCalled();
      });
    
    });
    

    With the first test we expect to call MyService.doThing() function. On other hand, if you have invalidInput as true, the previous function should not be called.

    I hope It helps.

提交回复
热议问题