mdasberg / ng-apimock

Node plugin that provides the ability to use scenario based api mocking: for local development for protractor testing
MIT License
99 stars 26 forks source link

Mocking external calls #51

Closed lazytesting closed 6 years ago

lazytesting commented 6 years ago

I'm trying to setup mocking for a Angular app and I'm running into some issues. What I did:

  1. run my angular app on localhost:4200
  2. create a server.js (mostly stolen from https://github.com/wswebcreation/rtc-demo-app). I set the rtcProxyOptions to
    {
    target: 'http://localhost:4200',
    changeOrigin: true,
    ws: false
    }
  3. create a few mocks
  4. node server.js

Now I see the mocks working for calls to localhost:4200/whatever. But for calls to other services (by example: localhost:1337/something ) the mocks are not called.

the mock config looks like this:

{
    "expression": "http://localhost:1337/something",
    "method": "GET",
    "name": "something",
    "isArray": false,
    "responses": {
      "success": {
        "default": true, 
        "status": 200, 
        "headers": {     }, 
        "file": "fixtures/Mocks/bla.json"
      }
    }
  }

I assume that I somehow need to configure that localhost:1337 needs to be proxied as well, but not sure how to do that. Could you please advice?

Thanks in advance!

mdasberg commented 6 years ago

@lazytesting I think it is because you have the following expression:

"expression": "http://localhost:1337/something",

This expression is used to match the url. If you change it to:

"expression": "/something",

it should work

lazytesting commented 6 years ago

hi @mdasberg thanks for your quick response! I tried changing the expression to only the path but that doesn't work either. But no luck yet. Anything other ideas?

lazytesting commented 6 years ago

This weekend I tried to narrow down the issue. I didn't found a way to get it working but I can reproduce it also with loading a simple file from google tag manager.

  1. Working mock url: http://localhost:3001/cargo/xxx/js/new-relic.js (same endpoint as my application)

    {
    "expression": "/xxx/assets/js/new-relic.js",
    "method": "GET",
    "name": "nr",
    "isArray": false,
    "responses": {
      "success": {
        "default": true, 
        "status": 200, 
        "headers": {
        },
        "data" : "hoi"
      }
    }
    }
  2. Not working mock url: https://www.googletagmanager.com/gtm.js?id=GTM-XXX

    {
    "expression": "/gtm.js?id=GTM-XXX",
    "name": "gtm",
    "method": "GET",
    "isArray": false,
    "responses": {
      "success": {
        "default": true, 
        "status": 200, 
        "headers": {
        },
        "data" : "hoi"
      }
    }
    }

My Express config:

const express = require('express');
const proxy = require('http-proxy-middleware');
const ngApimockRequest = require('ng-apimock/lib/utils');
const ngApimock = require('ng-apimock')();

const ngApimockConfig = {
  src: "./mock/config",
  outputDir: ".tmp/ngApimock",
};
ngApimock.run(ngApimockConfig);
ngApimock.watch(ngApimockConfig.src);

const app = express();
const rtcProxyOptions = {
  target: 'http://localhost:4200',
  changeOrigin: true,
  ws: false
};
app.set('port', (process.env.PORT || 3001));

app.use('/mocking', express.static('.tmp/ngApimock'));
app.use(ngApimockRequest.ngApimockRequest);
app.use('/', proxy(rtcProxyOptions));

app.listen(app.get('port'), function () {
  console.log('app running on port', app.get('port'));
});
yuriyShevchuk commented 6 years ago

I have the same issue: didn't figure out yet how to proxy external https calls.

wswebcreation commented 6 years ago

@mdasberg

The config @lazytesting has only routes to his localhost:4200 server, not to an other server. I never had to do this, but is ngApimock also possible to mock to server A and B with the same instance of ng-Apimock? Because I think that's the question of @lazytesting and @yuryShevhcuk

wswebcreation commented 6 years ago

@lazytesting

I figured it out and I hope I understand what you want, but first let me give some background for ng-Apimock. This module will can only mock all API's on 1 domain, so for example, if your API's are on domain example.com/api/, then you can only mock all eindpoints on that domain. The automation support for Protractor can also only handle 1 domain, which is the domain (for example localhost:4200) your mockserver is running on.

If I understand your question correct you want to mock for example localhost:4200 and localhost:1337. You need to see these as 2 domains and that can't be mocked (You are able to mock this by setting up 2 mockservers, but then you'd still have no automation support and it would fail to achieve its objectives.), and also not automated with Protractor.

I hope I understood you correct and I also gave a clear explanation. If so and your question has been answered, please close the issue. It's still open for discussion.

Grtz

Wim

lazytesting commented 6 years ago

@wswebcreation thanks for your detailed explanation! Indeed I need to mock calls to multiple domains and also my webapp is running on a different port/domain then the API's I'm calling.