Nock не перехватывает запросы - Ошибка: getaddrinfo ENOTFOUND - PullRequest
0 голосов
/ 01 мая 2019

Позвольте мне сначала объяснить, как все настроено.

  • Тесты выполняются с использованием Jest.
  • У меня есть jest.config.json со следующей строкой:
    • "globalSetup": "<rootDir>/__tests__/setup.js",
  • В setup.js У меня есть следующее содержание:

Как видите, я поместил фальшивый URL в переменную окружения AMA_API. После этого мне требуется ./nock.ts и логин строки Nock init done. Остальное содержимое этого файла мне не важно.

module.exports = async function() {
    console.log('[JEST SETUP] setting env var')
    process.env.AMA_API = 'http://fake.local'

    require('tsconfig-paths').register()
    require('ts-node').register({
        lazy: true,
        fast: true,
        project: 'tsconfig.json'
    })

    require('./nock.ts')
    console.log('Nock init done.')
    const connections = await require('src/db/connection.ts').initConnection()
    await require('./clearDb.ts').clearDB()
    await require('./initDb.ts').initializeDB()
    await Promise.all(connections.map(con => con.close()))
    console.log(`Connection setup complete [${connections.length} Connection${connections.length > 1 ? 's' : ''}]`)
    return true
};
  • В nock.ts у меня есть следующее содержание:
import * as nock from 'nock';

const FAKE_ANALYST_USER_CREATED = {
   ... (some large object)
}

console.log('NOCK URL ' + process.env.AMA_API);

nock(process.env.AMA_API)
  .persist()
  .log(console.log)
  .post('api/analyst/create-analyst-user')
  .reply(200, FAKE_ANALYST_USER_CREATED)

  • Это все настройки для nock, которые у меня есть. Затем в teams.controller.spec.ts у меня есть следующий тест:
describe('Team Endpoint', () => {
    let connections: Connection[];

    beforeAll(async () => {
        connections = await initConnection();
    });

    afterAll(async () => {
        await Promise.all(connections.map(con => con.close()));
        console.log('connection closed');
        return true;
    });

    describe('Team', () => {
        test.only('POST / should return [200 - OK] and create a new team', async () => {
            const newTeam = {
                ...
            };

            let response = await request(app)
                .post('/')
                .set('Authorization', adminUserToken())
                .send(newTeam);

            expect(response.status).toBe(201);
            expect(response.body).toHaveProperty('name', newTeam.name);
            expect(response.body).toHaveProperty('slug', newTeam.slug);
            expect(response.body).toHaveProperty('apiKey');
            expect(response.body.apiKey).toBeDefined();

            response = await request(app)
                .delete(`/${response.body.id}`)
                .set('Authorization', adminUserToken())
            expect(response.status).toBe(200);
        });
    });
});
  • Затем, наконец, этот тест вызывает функцию в teams.controller.ts со следующим содержимым:
import { Request, Response } from 'express';
import * as jwt from 'jsonwebtoken';
import * as rp from 'request-promise';
import { config } from 'src/config';
import { Brackets } from 'typeorm/query-builder/Brackets';
import { isUUID } from 'validator';
import { withConnection, withTransaction } from '../../db/connection';
import { Team } from '../../models/team';

/**
 * Create a new user
 */
export async function create(req: Request, res: Response) {
  const result = await withTransaction(async em => {
    const teamRepository = em.getRepository(Team)


    ... (irrelevant code)


    console.log('AMA URL ' + process.env.AMA_API)

    const response = await rp({
      uri: `${process.env.AMA_API}/api/analyst/create-analyst-user`,
      method: 'POST',
      json: true,
      headers: {
        'accept': 'application/json',
        'content-type': 'application/json',
        'authorization': 'Bearer ' + jwt.sign({
          id: -1,
          role: 'admin',
          team: '*',
        },
        config.secrets.session,
        {
          expiresIn: 60 * 60
        })
      },
      body: {username: newTeam.name, id: newTeam.id}
    });

    return response

  })

  if (result) {
    return res.status(201).send(result)
  }
}

Так что с этим все в стороне .. Весь код установки достигается при выполнении тестов (на основе вывода консоли, который я вижу). Однако когда я запускаю тесты, запрос в последнем блоке кода не перехватывается, я получаю следующий вывод:

Determining test suites to run...[JEST SETUP] setting env var
NOCK URL http://fake.local
Nock init done.
Starting server for profile test...
[Team] Adding initial teams
Connection setup complete [1 Connection]

 RUNS  src/api/teams/teams.controller.spec.ts
 RUNS  __tests__/server.spec.ts

Test Suites: 0 of 2 total
Tests:       0 total
Snapshots:   0 total
 PASS  __tests__/server.spec.ts
  ● Console    console.log __tests__/jest.js:1      [JEST SETUP] setting timeout to 10s
 FAIL  src/api/teams/teams.controller.spec.ts (6.488s)  ● Console

    console.log __tests__/jest.js:1
      [JEST SETUP] setting timeout to 10s    console.log src/config/index.ts:8
      Starting server for profile test...    console.log src/api/teams/teams.controller.ts:90
      AMA URL http://fake.local    console.log src/api/teams/teams.controller.spec.ts:16
      connection closed
  ● Team Endpoint › Team › POST / should return [200 - OK] and create a new 
team

    RequestError: Error: getaddrinfo ENOTFOUND fake.local fake.local:80

      at new RequestError (node_modules/request-promise/node_modules/request
-promise-core/lib/errors.js:14:15)
      at Request.plumbing.callback (node_modules/request-promise/node_module
s/request-promise-core/lib/plumbing.js:87:29)
      at Request.RP$callback [as _callback] (node_modules/request-promise/no
de_modules/request-promise-core/lib/plumbing.js:46:31)
      at self.callback (node_modules/request/request.js:185:22)
      at Request.Object.<anonymous>.Request.onRequestError (node_modules/req
uest/request.js:881:8)

Я уже часами пытался выяснить, что здесь не так ... безуспешно. Буду очень признателен за любую помощь.

Ответы [ 2 ]

1 голос
/ 06 мая 2019

В случае, если у кого-то есть такая же проблема. Перемещение инициализации nock в beforeall исправило это для меня.

0 голосов
/ 02 мая 2019

Это действительно хорошее время для использования Nock Recorder . Он запишет вам HTTP-вызовы и даст вам понять, почему Nock не соответствует запросу.

Попробуйте это в вашем teams.controller.ts:

import { Request, Response } from 'express';
import * as jwt from 'jsonwebtoken';
import * as rp from 'request-promise';
import { config } from 'src/config';
import { Brackets } from 'typeorm/query-builder/Brackets';
import { isUUID } from 'validator';
import { withConnection, withTransaction } from '../../db/connection';
import { Team } from '../../models/team';
const nock = require('nock')  // add Nock
nock.recorder.rec({
    output_objects: true,
  })  // Setup Nock to Record

/**
 * Create a new user
 */
export async function create(req: Request, res: Response) {
  const result = await withTransaction(async em => {
    const teamRepository = em.getRepository(Team)


    ... (irrelevant code)


    console.log('AMA URL ' + process.env.AMA_API)

    const response = await rp({
      uri: `${process.env.AMA_API}/api/analyst/create-analyst-user`,
      method: 'POST',
      json: true,
      headers: {
        'accept': 'application/json',
        'content-type': 'application/json',
        'authorization': 'Bearer ' + jwt.sign({
          id: -1,
          role: 'admin',
          team: '*',
        },
        config.secrets.session,
        {
          expiresIn: 60 * 60
        })
      },
      body: {username: newTeam.name, id: newTeam.id}
    });

    nock.restore()  // stop nock recording
    const nockCalls = nock.recorder.play() // "play" the recording into a variable
    console.log(`Nock Captured Calls: \n${JSON.stringify(nockCalls,null,2)}`) // inspect calls that Nock recorder

    return response
  })

  if (result) {
    return res.status(201).send(result)
  }
}
...