Protractor addMockModule and $httpProvider interceptor
Asked Answered
A

1

8

This question is a possible solution for my other question (where they advice to use addMockModule from protractor): Call other api when running tests using Protractor.

I have the following file: mockedRest.js this is the module I want to add to protractor. It should intercept any REST calls and replace the address (api/ to apiMock/).

exports.apiMockModule = function () {

    console.log('apiMockModule executing');

    var serviceId = 'mockedApiInterceptor';
    angular.module('apiMockModule', ['myApp'])
        .config(['$httpProvider', configApiMock])
        .factory(serviceId,
        [mockedApiInterceptor]);

    function mockedApiInterceptor() {
        return {
            request: function (config) {
                console.log('apiMockModule intercepted');
                if ((config.url.indexOf('api')) > -1) {
                    config.url.replace('api/', 'apiMock/');
                }

                return config;
            },
            response: function (response) {
                return response
            }
        };
    }

    function configApiMock($httpProvider) {
        $httpProvider.interceptors.push('mockedApiInterceptor');
    }
};

Then I have my actual test where I load the module.

describe('E2E addMockModule', function() {
    beforeEach(function() {
        var mockModule = require('./mockedRest');
        browser.addMockModule('apiMockModule', mockModule.apiMockModule);
        console.log('apiMockModule loaded');
        browser.get('#page');
    });
    it('tests the new apiMock', function() { 
        // test that clicks a button that performs a rest api call. left out as I can see the call in fiddler.
    });
});

However, the REST call is still pointing to 'api/' instead of 'apiMock/' I don't know if I have to do anything more in order to get the interceptor to do its work. It's also worth to note that there isn't anything logged to console inside the apiMockModule, like it isn't loading the module.

Any advice is appreciated.

Amylolysis answered 17/6, 2014 at 9:5 Comment(0)
E
11

I make two minor bug fixes in mock module to make it works.

  • the mock module don't need to depend on your application,
  • the config.url have to be set by the transformed one.

The updated mockedRest.js :

exports.apiMockModule = function () {

  console.log('apiMockModule executing');

  var serviceId = 'mockedApiInterceptor';
  angular.module('apiMockModule', [])
      .config(['$httpProvider', configApiMock])
      .factory(serviceId,
      [mockedApiInterceptor]);

  function mockedApiInterceptor() {
      return {
          request: function (config) {
              console.log('apiMockModule intercepted');
              if ((config.url.indexOf('api')) > -1) {
                config.url = config.url.replace('api/', 'apiMock/');
              }

              return config;
          },
          response: function (response) {
              return response
          }
      };
  }

  function configApiMock($httpProvider) {
      $httpProvider.interceptors.push('mockedApiInterceptor');
  }
};

I have tested this code in this environment:

  • protractor 0.24.1
  • angular 1.2.16
  • ChromeDriver 2.10.267517
  • Google chrome 35.0.1916.153
  • Mac OS X 10.9.3 x86_64

You wrote:

There isn't anything logged to console inside the apiMockModule

It is normal, the module code is not executed by protractor, but sent to the browser (using driver.executeScript). So the code is executed by the browser.

But it is possible to get the logs from the browser for debugging:

...
it('tests the new apiMock', function() {
  browser.manage().logs().get('browser').then(function(browserLog) {
    console.log('log: ' + require('util').inspect(browserLog));
  });
...
Elene answered 17/6, 2014 at 12:21 Comment(9)
thanks for clarification and your bugfixes but it's still not working. Is there any other way I can debug this? Even if I set config.url = 'something' it isn't using that valueAmylolysis
I have completed my answer.Elene
I've marked as answer. There is probably something wrong with my code but I can't find it. The interceptor is never fired. Do you still have your test code as a small app? What version of protractor do you use? Thanks a lot for your efforts and help!Amylolysis
No problem, i would have wanted you solve your problem. I still have this test code but with my app (which is not small)...Elene
I complete my answer with my the test environment.Elene
I took the time to setup a demo app that does just this (but still fails). If you got the time to have a look at it... just modify the protractor conf file for your server. Thanks dropbox.com/s/sjkwgji8b3lz9ou/DemoApp.zip (8.06kb)Amylolysis
Let us continue this discussion in chat.Elene
working for me. look also hereEquip
I have a problem where adding a mock module is breaking my element locators. Does anyone have experience with that?Nicole

© 2022 - 2024 — McMap. All rights reserved.