mercredi 5 août 2015

How to test controller async behavior without using Timeout

So I have a controller like this:

angular.module('someModule').controller('someController',function(productService) {
   $scope.products = [];
   $scope.init = function() {
      aService.fetchAll().then(function(payload) {
          $scope.products = filterProducts(payload.data);
      });
   }
   $scope.init();

   function filterProducts(products) {
      //for each of products filter some specific ones
      return filteredProducts;
   }
});

I am writing a test that will call the $scope.init() and has to verify that the products were filtered appropriately. I am mocking the $httpBackend so the code looks like this:

describe("someController", function() {
    "use strict";
    var $controller; //factory
    var controller; //controller
    var $rootScope;
    var $state;
    var $stateParams;
    var $injector;
    var $scope;
    var $httpBackend;
    var productService;

    beforeEach(function(){
        angular.mock.module("someModule")


        inject(function (_$rootScope_, _$state_, _$injector_, $templateCache, _$controller_, _$stateParams_, _$httpBackend_, _productService_) {
            $rootScope = _$rootScope_;
            $state = _$state_;
            $stateParams = _$stateParams_;
            $injector = _$injector_;
            $controller = _$controller_;
            $httpBackend = _$httpBackend_;
            productService = _productService_;
        });
        controller = $controller("someController", {$scope: $scope, $state: $state});
    });


    it("init() should filter products correctly",function(){
        //Arrange
        var expectedFilteredProducts = ["1","2"];
        var products = ["0","1","2"];
        $httpBackend.whenGET("api/products").respond(products);

        //Act
        $scope.init();

        //Assert
        setTimeout(100,function(){
            expect($scope.products).toEqual(expectedFilteredProducts);
        });
    });
});

The problem is that without the setTimeout the test doesn't pass. Is there a way to test what I am trying to do without it and without introducing complex $q/promises just for the test? As a side note productService is returning a promise $http. Thanks.

Aucun commentaire:

Enregistrer un commentaire