Nock无法拦截请求-错误:getaddrinfo ENOTFOUND

时间:2019-05-01 09:00:32

标签: node.js typescript express jestjs nock

首先让我解释一下如何设置所有内容。

  • 使用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 个答案:

答案 0 :(得分:0)

这是使用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)
  }
}

答案 1 :(得分:0)

万一有人遇到同样的问题。将nock初始化移到所有步骤之前,对我来说都是固定的。