2017-04-10 54 views
1

我希望能夠打開和關閉我的angularJS應用程序中的$ httpBackend模擬。

這意味着我想要注入$ httpBackend /懶惰/按需。 能夠打開和關閉它也是很好的。

例如爲從CMS預覽的AngularJS應用程序提供輸入數據。

下面的代碼只有在將ngMockE2E移動到普通的依賴項時才起作用,並且將$ httpBackend注入我的工廠的標準方式。

代碼設置UPP $ httpBackend從一個配置文件中的所有呼叫,然後迴應所有的人......

const registerCalls =() => { 
    const injectormock = angular.injector(['ngMockE2E']); //lazy load not working as expected 
    const $httpBackend = injectormock.get('$httpBackend'); //lazy load not working as expected. 
    //Pass through for resources: 
    $httpBackend.whenGET(/.*.html/).passThrough(); 
    $httpBackend.whenGET(/.*.json/).passThrough(); 
    //API calls should be mocked: 
    const apiCalls = {}; 
    for (var call in apiConfig) { 
     if ({}.hasOwnProperty.call(apiConfig, call)) { 
      const callConfig = apiConfig[call]; 
      const url = angular.isDefined(callConfig.regex) ? callConfig.regex : callConfig.url(); 
      if (callConfig.method === 'GET') { 
       apiCalls[call] = $httpBackend.whenGET(url); 
      } else if (callConfig.method === 'POST') { 
       apiCalls[call] = $httpBackend.whenPOST(url); 
      } 
     } 
    } 
    return apiCalls; 

} 

const success = function() { 
    const apiCalls = registerCalls(); 
    for (var call in apiConfig) { 
     let response = {}; 
     if (angular.isDefined(apiConfig[call].response)) { 
      response = apiConfig[call].response(); 
     } 
     apiCalls[call].respond(200, response); 
    } 
}; 

我怎樣才能設置了$ httpBackend,以便它可以被激活/停用而AngularJS應用程序正在運行?

回答

1

角度服務是在第一次注入時被懶惰地實例化的單例。如果在應用程序引導時執行$httpBackend的注入(通常在使用$http的情況下),則無法模擬服務。

通過angular.injector獲得E2E $httpBackend版本是顯而易見的,但卻是錯誤的做法。這將導致擁有使用自己的核心服務單例的新注入器實例($browser等)。

乾淨的方法是通過全球angular.mock.e2e,如this example所示。它將可用once angular-mocks.js is loaded。重點是裝飾$httpBackend(這是一個函數)來包裝原始和E2E實現並有條件地使用它們。

這是可以做到這樣的:

angular.module('mockableHttp', []) 
.decorator('$httpBackend', function ($injector, $delegate) { 
    var $httpBackendOriginal = $delegate; 
    var $httpBackendE2E = $injector.invoke(angular.mock.e2e.$httpBackendDecorator, null, { 
    $delegate: $delegate 
    }); 

    function $httpBackend() { 
    var $httpBackendImplementation = $httpBackend.isMocking 
     ? $httpBackendE2E 
     : $httpBackendOriginal; 

    return $httpBackendImplementation.apply(this, arguments); 
    } 

    return Object.assign($httpBackend, $httpBackendE2E, { 
    enableMocking: function() { 
     $httpBackend.isMocking = true; 
    }, 
    disableMocking: function() { 
     $httpBackend.isMocking = false; 
    } 
    }); 
}); 

mockableHttp在應用程序模塊被裝載(可完全排除在生產)和HTTP嘲笑與$httpBackend.enableMocking()激活。

+0

非常好的答案,模式完美無缺 –

+0

很高興爲你工作。 – estus