【发布时间】:2015-03-31 20:07:56
【问题描述】:
我正在尝试在 Protractor 测试中模拟对 API 调用的响应。在不同的测试中(以及在测试中),应用程序将 POST 到一个 API(始终是相同的 URL),并发布不同的数据,并期待不同的响应。
具体来说,它是一个搜索引擎,我发送不同的查询并期望得到不同的结果。我让它像下面的代码一样成功运行,但它变得难以管理:
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) 它不起作用。清除并添加第二个模拟后,getRegisteredMockModules() 仅显示第二个模拟,但似乎第一个模拟仍在使用中,基于 expects 和在将browser.pause() 与 ChromeDriver 一起使用时的手动检查。看来你不能在不至少重新加载页面的情况下更改模拟。
2) 即使它确实有效,但每个模拟模块都有大量重复代码,因为它必须设置所有内容,包括 passThrough()。
如果我可以将我想要的响应传递到我正在添加的模拟中,那就更好了,但是我尝试过,并且传递到我自己的函数中的任何内容在 angular.module 范围内都不可用。我能想到的唯一方法是创建另一个带有提供者的角度模块,该提供者具有一个变量,可以跟踪所需的响应,并将其注入到模拟模块中。我还没有尝试过,但这似乎是一个不必要的复杂解决方案。
【问题讨论】:
标签: angularjs mocking protractor