Call other api when running tests using Protractor
Asked Answered
F

1

3

I currently have setup some tests using protractor. These tests are retrieving data from a WebApi. However, I want to point the WebApi calls to a real but mocked WebApi that just returns the objects I want to use as test data.

For example, the current request is:

http://localhost/myApp/api/profile/getUser/1

I want to manipulate this request so the test will use:

http://localhost/myApp/apiMock/profile/getUser/1

First I thought to write an interceptor that changes the request header but I don't have a clue how to make this work with Protractor. I can't use angular directly within my protractor tests, can I? If I can, writing the interceptor isn't a problem, I just don't know how to plug it in for my tests in protractor.

I've read the following post: E2E and Mocking but it doesn't fulfill my needs as I don't want to call the same url over and over again, I want to replace (part of) the dynamic url to point to the mocked api service.

Just to make myself more clear, I'm not looking for mocked data on the client side. I want to keep the API calls (in my opinion it's more E2E) but just point to another API url that returns mocked data.

Foursome answered 16/6, 2014 at 13:22 Comment(6)
Where the api url is defined in your code ?Allinclusive
each controller has its own service that handles http calls. Inside the service there is a variable that contains the base address ('api/profile/'). The function itself (where we invoke $http), adds the correct action (apiUrl + 'getuser/' + userid) to the url parameter.Foursome
The base address ('api') could be defined using angular.constant then injected in your service. And your protractor test you replace the base address by the mock one ('apiMock').Allinclusive
thanks, indeed, it's similar as by intercepting the API call. But how to can I change the constant value in protractor? Whenever I call angular, it says 'angular is not defined'Foursome
You should use ptor.addMockModule. eitanp461.blogspot.fr/2014/01/advanced-protractor-features.htmlAllinclusive
thanks, I already looked into that but I was stuck because of the lack of documentation. Your link made it more clear, but I still have an error when trying it out. I made a new question #24260246Foursome
F
1

The problem can be solved by adding a addMockModule

more details here: Protractor addMockModule and $httpProvider interceptor

solution:

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

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() { 
        // your test that clicks a button that performs a rest api call. 
    });
});

Credits go to @gontard

Foursome answered 17/6, 2014 at 13:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.