如何在量角器测试httpBackendMocks之间切换 [英] How to switch between httpBackendMocks in protractor test

查看:201
本文介绍了如何在量角器测试httpBackendMocks之间切换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图嘲弄到量角器测试中的API调用的响应。在不同的测试(测试和内部),应用程序将发布一个API(总是相同的URL)以HTTP POST,并期待不同的反应不同的数据。

I am trying to mock responses to API calls within Protractor tests. In different tests (and within tests), the application will POST to an API (always the same URL) with different data POSTed, and expecting different responses.

具体而言,它是一个搜索引擎,我送不同的查询和期待不同的结果了。我有它成功的工作像下面的code,但它越来越难以管理:

Specifically, it is a search engine, and I am sending different queries and expecting different results back. I have it working successfully like the code below, but it is getting unmanageable:

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 并在必要时加嘲弄,像这样:

What I'd like to do is have each possible response in a separate mock, then remove the beforeEach and add the mocks when needed, like so:

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()只显示第二模拟,但它似乎是第一个模拟仍然习惯的基础上,使用 browser.pause()与ChromeDriver时想到和人工检查。看来,你不能没有,至少重新加载页面更改模拟。

1) It doesn't work. After clearing and adding the second mock, getRegisteredMockModules() shows only the second mock, however it seems like the first mock is still getting used, based on the expects and manual inspection when using browser.pause() with ChromeDriver. It seems that you can't change the mocks without at least reloading the page.

2),即使没有工作,没有重复code的每个模拟模块,数额巨大,因为它建立的一切,包括直通()

2) Even if it did work, there is a huge amount of repeated code for each mock module, as it has to set up everything, including the passThrough().

是什么更妙的是,如果我可以通过我的期望的响应为我添加了模拟,但我想,和任何传递到我自己的函数是不是在现有的 angular.module 范围。我能想到的唯一办法做到这一点是创建一个供应商,有一个变量,将保持其响应所需曲目,然后注入到这一点嘲笑模块另一个角度模块。我还没有试过,但但它似乎是一个不必要的复杂的解决方案。

What would be even better would be if I could pass my desired response into the mock I am adding, however I tried that and anything passed into my own function isn't available within the angular.module scope. The only way I could think of to do that would be to create another angular module with a provider that had a single variable that would keep track of which response was desired, and inject that into the mocked module. I haven't tried that yet but it seems like an unnecessarily complex solution.

推荐答案

一个模拟模块量角器基本上是$该被执行成在每次整页刷新浏览器C $℃。这是一个机制,以节省您这样做,自己的麻烦,因为这样的刷新完全清除浏览器的状态(当然是有饼干除外)。正如你已经发现了,直到触发这样一个刷新(以 browser.get()),您的模块不能执行。您可以手动做到这一点与 browser.executeScript()如果你想。

A mock-module in protractor is basically code that gets executed into the browser upon each full-page-refresh. It's a mechanism to save you the hassle of doing that yourself, since such a refresh cleans the state of the browser completely (with the exception of cookies of course). As you already found out, until you trigger such a refresh (with browser.get()), your modules are never executed. You can do that manually with browser.executeScript() if you want.

对于从嘲笑后端随之而来的混乱 - 我采取了以下做法:
为您的后端默认模拟实现,同时也使容易重写,并用初始化函数每次测试前对其进行注册:

Regarding the mess that ensues from mocking your back-end - I took the following approach: Have a default mock implementation for your back-end while making it easily overridable and registering it before each test with an init function:

嘲笑后端-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 块将其删除:

If you need parts of it overridden at some point register a new mock module. Remove it in your afterEach block:

嘲笑后端-特殊user.js的

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

的TestFixture 是保存我们的数据,并在嘲笑后端基地之前登记了另一个模块

The testFixture is from another module that holds our data and is registered before the mocked-backend-base:

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);

这篇关于如何在量角器测试httpBackendMocks之间切换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆