테스트를 위해 ExpressJS 인스턴스를 프로그래밍 방식으로 종료하려면 어떻게합니까?


106

Express 인스턴스를 종료하는 방법을 알아 내려고합니다. 기본적으로 .listen(port)호출 의 반대를 원합니다. Express 서버가 수신을 중지하고 포트를 해제하고 완전히 종료하도록하려면 어떻게해야합니까?

나는 이것이 이상한 쿼리처럼 보일 수 있다는 것을 알고 있으므로 여기에 컨텍스트가 있습니다. 아마도 이것에 접근하는 다른 방법이 있을지도 모르지만 나는 그것에 대해 잘못된 방식으로 생각하고 있습니다. 내 socket.io/nodejs 앱에 대한 테스트 프레임 워크를 설정하려고합니다. 단일 페이지 앱이므로 테스트 스크립트에서 ( Mocha를 사용하고 있습니다.,하지만 그게 중요하지 않습니다.) 서버를 시작하고 이에 대해 테스트를 실행 한 다음 서버를 종료 할 수 있기를 원합니다. 테스트가 시작되기 전에 서버가 켜져 있다고 가정하거나 테스트 중 하나가 서버를 시작하도록하고 모든 후속 테스트가 작동한다고 가정하여이 문제를 해결할 수 있지만, 정말 지저분합니다. 각 테스트 파일이 적절한 설정으로 서버 인스턴스를 시작한 다음 테스트가 끝나면 해당 인스턴스를 종료하는 것을 선호합니다. 즉, 테스트 실행에 이상한 종속성이 없으며 모든 것이 깨끗합니다. 또한 시작 / 종료 테스트를 수행 할 수 있음을 의미합니다.

그래서, 이것을하는 방법에 대한 조언이 있습니까? 수동으로 예외를 트리거하여 예외를 발생시키는 것에 대해 생각했지만 지저분 해 보입니다. Express 문서와 소스를 살펴 봤지만 서버를 종료하는 방법을 찾을 수없는 것 같습니다. 이를 위해 socket.io에 무언가가있을 수도 있지만 소켓 서버가 Express 서버에 연결되어 있기 때문에 Express 계층에서 발생해야한다고 생각합니다.

답변:


156

Express 서버가 더 이상 노드 http 서버에서 상속하지 않기 때문에 상황이 변경되었습니다 . 다행히 app.listen은 서버 인스턴스를 반환합니다.

var server = app.listen(3000);

// listen for an event
var handler = function() {
  server.close();
};

23
Mocha 테스트의 경우 ( 'app') 필요한 경우 앱 개체로 확장합니다. app.server = app.listen (3000); 그래서 나중에 말할 수 있습니다 : var app = require ( './ app'); app.server.close ();
Jack Chi

2
서버를 테스트 할 때 github.com/visionmedia/supertest를 확인하면 실제 서버를 실행 하지 않고도 테스트 할 수 있습니다
Lukas Liesis

server.close()후크 내에서 호출 하는 경우 done 콜백을 전달하는 것이 좋습니다 .
Ullauri

참고 : Express Application 인스턴스 인 'app'과 'close'메서드가있는 기본 네이티브 HTTP Server 인스턴스 인 'app.listen'의 반환 값 사이에는 큰 차이가 있습니다. @JackChi는 위에서 이것을 암시했습니다.
ajxs

이로 인해 열린 상태로 남아있는 열린 클라이언트 소켓에 문제가 발생하지 않습니까?
Cameron Tacklind

18

사용 app.close(). 전체 예 :

var app = require('express').createServer();
app.get('/', function(req, res){
  res.send('hello world');
});
app.get('/quit', function(req,res) {
  res.send('closing..');
  app.close();
});
app.listen(3000);

전화 app.close()테스트가 종료 한 때 콜백 내부. 그러나 프로세스가 여전히 실행 중임을 기억하십시오 (더 이상 듣고 있지 않음).

그 후에 프로세스를 종료해야하는 경우을 호출하십시오 process.exit(0).

연결:

app.close : http://nodejs.org/docs/latest/api/http.html#server.close (동일하게 적용됨)

process.exit : http://nodejs.org/docs/latest/api/process.html#process.exit


1
완벽합니다. 정확히 제가 찾던 것입니다. 내가 완전히 이해하지 못했던 핵심 노드 http 서버를 확장했기 때문에 Express에서 찾지 못한 것 같습니다. 감사!
drewww dec

Srijan 덕분에, 그의는 나도 도움이
아담 홉 킨슨에게

여전히 사실입니까? express.createServer는 더 이상 사용되지 않는 것으로 표시되고 앱이 더 이상 http.js의 서버에서 상속되지 않는다는 오류를 표시합니다
Frank Schwieterman 2013 년

4
이 때문에 유효하지 않습니다 특급 3
gprasant

4
이와 같이 서버를 닫기위한 URL을 노출하는 것은 IMHO에 대한 좋은 생각이 아닙니다.
shime

2

"HTTP 서버를 종료하는 방법"의 변형에 대해 여러 번 대답했습니다. 지원 채널. 안타깝게도 기존 라이브러리 는 한 가지 또는 다른 방식으로 부족 하기 때문에 추천 할 수 없습니다 . 그 이후로 나는 정상적인 HTTP 서버 종료에 대해 예상되는 모든 경우를 처리하는 패키지를 작성했습니다.

https://github.com/gajus/http-terminator

http-terminator 의 주요 이점 은 다음과 같습니다.

  • 원숭이 패치 Node.js API가 아닙니다.
  • 첨부 된 HTTP 요청없이 모든 소켓을 즉시 파괴합니다.
  • 지속적인 HTTP 요청이있는 소켓에 대한 우아한 타임 아웃을 허용합니다.
  • HTTPS 연결을 올바르게 처리합니다.
  • 연결을 설정하여 연결 유지를 사용하여 서버가 종료되었음을 알립니다. 헤더 닫기
  • Node.js 프로세스를 종료하지 않습니다.

Express.js에서 사용 :

import express from 'express';
import {
  createHttpTerminator,
} from 'http-terminator';

const app = express();

const server = app.listen();

const httpTerminator = createHttpTerminator({
  server,
});

await httpTerminator.terminate();


-1

서버를 시작하고, 테스트를 실행하고, 서버를 중지하는 bash 스크립트를 작성하여 쉽게 수행 할 수 있습니다. 이는 모든 테스트를 빠르고 쉽게 실행할 수 있도록 해당 스크립트에 별칭을 지정할 수 있다는 장점이 있습니다.

전체 연속 배포 프로세스에 이러한 스크립트를 사용합니다. 이에 대한 통찰력을 얻으려면 Jon Rohan의 Dead Simple Git Workflow 를 참조하십시오.


2
이것은 작동하지만 가능한 경우 bash없는 솔루션을 선호합니다. 어리석은 환경 일 수도 있지만 서버 구성 별 테스트 + 시작 / 종료 테스트를 더 쉽게 작성할 수 있기 때문에 테스트 컨텍스트에서 서버를 시작 / 중지하고 싶습니다. 또한 별도의 스크립트를 통해 서버 관련 테스트를 실행해야하는 간접적 인 문제도 발생하지 않습니다.
drewww dec

환경 별 테스트를 작성하는 이유는 무엇입니까? 내가 틀렸을지도 모르지만 이것은 나에게 나쁜 습관이된다. 개발 환경에 관계없이 테스트가 팀 전체에서 작동하기를 원하므로 테스트에서 환경에 구애받지 않으려 고 노력할 것입니다.
Josh Smith

나는 여기서 환경과 관련된 어떤 것도하고 있지 않다고 생각한다. 서버에 대한 몇 가지 다른 시작 옵션 (파일에서 구성 옵션 읽기, 데이터 저장소에서 상태로드 등)이있을 것이므로 다른 모든 것을 테스트하는 동일한 프레임 워크에서 테스트하는 것이 좋습니다. 예를 들어 서버를 종료하고 다시 백업하고 프로세스에서 상태가 손실되지 않았는지 확인하는 테스트도 받고 싶습니다. bash에서 코드를 테스트하는 것보다 노드에서 프로그래밍 방식으로 수행 할 수 있다면 더 쉽습니다.
drewww

bash 자체에 테스트 코드를 배치하지 않습니다. 명령 줄에서 직접 수행하는 것처럼 서버를 시작하고 스크립트에서 테스트를 실행하기 만하면됩니다. 거기에는 특별한 마법이 없습니다.
Josh Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.