2015-11-02 91 views
0

我有一個指令,注入的apiService是$ http和其他自定義服務的包裝。如何在指令測試中模擬服務?

,當我嘗試測試指令,我不知道如何嘲笑服務:

app.directive('coreMenu', ['apiService', function (apiService) { 
return { 
    restrict : 'E', 
    replace  : true, 
    templateUrl : 'Directives/CoreMenu.tpl.html', 
    link: function (scope) { 
     apiService.get({ 
      module: 'Core', 
      route: 'Menu' 
     }).then(function (response) { 
      scope.menuItems = response.data; 
     }, function (response) { 
      // error: no menu available 
     }); 
    } 
    }; 
}]); 

測試:

describe('coreMenu directive', function() { 
var $compile, $rootScope; 

beforeEach(function() { 
    module('AdminTechPortal'); 
    module('CoreLeftMenu.tpl.html'); 

    inject(function (_$compile_, _$rootScope_) { 
     $compile  = _$compile_; 
     $rootScope = _$rootScope_; 
    }); 

it('replaces the element with the appropriate content', function() { 
    var element = $compile("<core-menu></core-menu>")($rootScope); 
    $rootScope.$digest(); 

    expect(element.html()).toContain('id="core-menu"'); 
    }); 
}); 

該測試拋出(這是正常的):

Error: Unexpected request: GET /Core/Menu/

是否有可能使用$ httpbackend模擬apiService而不僅僅是xhr調用?

回答

1

我在這種情況下,做如下...熊(此方式)有一些工作,如果承諾需要鏈接,將會失敗!

describe('coreMenu directive', function() { 
    var $compile, $rootScope, apiServiceMock; 

    // BIG WARNING: 
    // This beforeEach() block MUST run before using any inject() 
    beforeEach(function() { 
     apiServiceMock = {}; 

     apiServiceMock.get = jasmine.createSpy('apiServiceMock.get').and.callFake(function() { 
      return { // mock the promise 
       then: function(successCb, errorCb) { 
        // keep the callbacks to call them at our convenience 
        apiServiceMock._successCb = successCb; 
        apiServiceMock._errorCb = errorCb; 
       } 
      }; 
     }); 

     module(function($provide) { 
      // override the apiService in the DI container 
      $provide.value('apiService', apiServiceMock); 
     }); 
    }); 

    beforeEach(function() { 
     module('AdminTechPortal'); 
     module('CoreLeftMenu.tpl.html'); 

     inject(function (_$compile_, _$rootScope_) { 
      $compile  = _$compile_; 
      $rootScope = _$rootScope_; 
     }); 
    }); 

    it('replaces the element with the appropriate content', function() { 
     var element = $compile("<core-menu></core-menu>")($rootScope); 
     $rootScope.$digest(); 

     // SAMPLE TESTS 
     expect(apiServiceMock.get).toHaveBeenCalledWith(...); 
     // test success 
     apiServiceMock._successCb(...); 
     expect(...) // things to expect on success 
     // test failure - probably in another it() 
     apiServiceMock._errorCb(...); 
     expect(...) // things to expect on error 
    }); 
}); 
+0

感謝您的解決方案 – CaptainMat

0

遵循以下步驟:

  1. 加$ httpBackend變量:
var $compile, $rootScope, $httpBackend; 
  • 進樣和分配上beforeEach
  • inject(function (_$compile_, _$rootScope_, _$httpBackend_) { 
        $compile  = _$compile_; 
        $rootScope = _$rootScope_; 
        $httpBackend = _$httpBackend_; 
    }); 
    
    1. 創建afterEach
    afterEach(function() { 
        $httpBackend.verifyNoOutstandingExpectation(); 
        $httpBackend.verifyNoOutstandingRequest(); 
    }); 
    
    記住,測試的承諾
  • 測試
  • it('replaces the element with the appropriate content', function() { 
        $httpBackend.expectGET('/Core/Menu/'); 
        var element = $compile("<core-menu></core-menu>")($rootScope); 
        $httpBackend.flush(); 
        $rootScope.$digest(); // Not sure if still needed 
        expect(element.html()).toContain('id="core-menu"'); 
    }); 
    
    相關問題