Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protractor addMockModule and $httpProvider interceptor

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.

like image 491
emp Avatar asked Jun 17 '14 09:06

emp


1 Answers

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));
  });
...
like image 165
gontard Avatar answered Oct 28 '22 00:10

gontard