2015-03-31 39 views
4

我試圖模擬對量角器測試中API調用的響應。在不同的測試中(以及在測試中),應用程序將發佈POST到不同的POST數據並期待不同的響應的API(始終是相同的URL)。如何在量角器測試中的httpBackendMocks之間切換

具體而言,它是一個搜索引擎,我發送不同的查詢並期待不同的結果。我有它成功的工作像下面的代碼,但它越來越難以管理:

var httpBackendMock = function() { 
    angular.module('httpBackendMock', ['ngMockE2E']) 
    .run(function($httpBackend) { 
     $httpBackend.whenPOST('//search_endpoint').respond(function(method, url, query, headers) { 
     query = JSON.parse(query); 
     if (query.bla = 'foo') { 
      var results = {... lots of json ...}; 
     } else if (query.bla = 'bar') { 
      var results = {... lots of json ...}; 
     } else if (query.something.else != 'whatever') { 
      var results = {... lots of json ...}; 
     ... etc ... 
     } else { 
      var results = {... lots of json ...}; 
     } 
     return [200, results]; 
     }); 
     $httpBackend.whenGET(/.*/).passThrough(); 
    }) 
}; 

beforeEach(function(){ 
    browser.addMockModule('httpBackendMock', httpBackendMock); 
}); 

我想什麼做的是有一個單獨的模擬每一個可能的反應,然後取出beforeEach並添加嘲笑需要時,如下所示:

it('paginates', function(){ 
    // mocking a search with 13 results, showing 10 results per page 
    browser.addMockModule('search_results', <some function>); 
    $('#searchbox').sendKeys('some keyword search'); 
    $('#searchbutton').click(); 
    expect($('#results li').count()).toEqual(10); 
    browser.clearMockModules(); 
    browser.addMockModule('search_results_page2', <some other function>); 
    $('#next').click(); 
    expect($('#results li').count()).toEqual(3) 
}); 

這有兩個問題。

1)它不起作用。在清除並添加第二個模擬之後,​​僅顯示第二個模擬,但是看起來第一個模擬仍在使用,基於expect和使用browser.pause()與ChromeDriver進行手動檢查。看起來,如果沒有至少重新加載頁面,你不能改變模擬。

2)即使它工作,每個模擬模塊都有大量的重複代碼,因爲它必須設置所有內容,包括passThrough()

如果我可以將所需的響應傳遞到我添加的模擬中,會更好的,但是我嘗試過,並且在angular.module範圍內傳遞給我自己的函數的任何東西都不可用。我能想到的唯一方法就是創建另一個帶有提供程序的角度模塊,該提供程序具有一個可以跟蹤所需響應的變量,並將其注入到模擬模塊中。我還沒有嘗試過,但它似乎是一個不必要的複雜解決方案。

回答

3

量角器中的模塊模塊基本上是在每次完整頁面刷新時執行到瀏覽器中的代碼。這是一種機制,可以讓您自己省卻麻煩,因爲這樣的刷新可以完全清除瀏覽器的狀態(當然,Cookie除外)。正如你已經發現的那樣,直到你觸發這樣的刷新(使用browser.get()),你的模塊將永遠不會執行。如果需要,您可以使用browser.executeScript()手動執行此操作。

關於從嘲笑你的後端隨之而來的混亂 - 我採取了以下做法: 對後端默認模擬實現,同時也使很容易克服的,並用初始化函數每次測試前對其進行註冊:

嘲笑,後端-base.js

exports.httpBackendMockBase = function() { 
    var exposeBackendCalls = function ($httpBackend) { 
     this.getLoginAuthenticated = $httpBackend.whenGET(/login\/authenticated.*/); 
     this.getFindStuff = $httpBackend.whenGET(/lookup\/findStuff.*/); 
     this.getFullProfile = $httpBackend.whenGET(/api\/full.*/); 
    }; 

    angular.module('httpBackendMockBase', ['myClientApp', 'ngMockE2E']) 
    .service('httpBackendMockBase', exposeBackendCalls) 
    .run(function (httpBackendMockBase, testFixture) { 
     httpBackendMockBase.getLoginAuthenticated.respond(function() { 
      return [200, null, {}]; 
     }); 
     httpBackendMockBase.getFindStuff.respond(function() { 
      return [200, { stuff: testFixture.stuff }, {}]; 
     }); 
     httpBackendMockBase.getFullProfile.respond(function() { 
      return [200, { profile: testFixture.fullProfile }, {}]; 
     }); 
    }); 
}; 

如果您需要在某一時刻覆蓋其部分註冊一個新的模擬模塊。刪除它在您的afterEach區塊中:

模仿後端特殊用戶。JS

exports.httpBackendMock = function() { 
    angular.module('httpBackendMockSpecialUser', []).run(function (httpBackendMockBase, testFixture) { 
     httpBackendMockBase.getLoginAuthenticated.respond(function() { 
      return [200, testFixture.specialUser, {}]; 
     }); 
    }); 
}; 

testFixture是保存我們的數據和嘲笑,後端基之前登記了另一個模塊:

fixture.js

exports.data = { 
    stuff: null, 
    fullProfile: {}, 
    specialUser: {} 
}; 

exports.module = function (data) { 
    angular.module('backendFixture', []).constant('testFixture', data); 
}; 

的初始化函數:

var fixtureModule = require('fixture'); 
var baseMockedBackend = require('mocked-backend-base'); 

browser.addMockModule('backendFixture', fixtureModule.module, fixtureModule.data); 
browser.addMockModule('httpBackendMockBase', baseMockedBackend.httpBackendMockBase); 
+0

「正如你已經發現的那樣,直到你觸發這樣的刷新(使用browser.get()),你的模塊纔會被執行。」謝謝! – chromaloop 2015-06-01 17:56:10

+0

似乎每次你做一個browser.get(),你必須事先做另一個browser.addMockModule,因爲如果你改變了URL,mocks就停止工作。 – 2016-08-03 18:07:41

+0

不應該如此。這樣做會打破模塊模塊的目的。 – 2016-08-04 11:58:50