Test için bir ExpressJS örneğini programlı olarak nasıl kapatırım?


109

Express'in bir örneğini nasıl kapatacağımı anlamaya çalışıyorum. Temel olarak, .listen(port)aramanın tersini istiyorum - bir Express sunucunun dinlemeyi DURDURMASINI, bağlantı noktasını serbest bırakmasını ve temiz bir şekilde kapatmasını nasıl sağlayabilirim?

Bunun garip bir sorgu gibi göründüğünü biliyorum, işte bağlam; belki buna yaklaşmanın başka bir yolu vardır ve ben bunu yanlış şekilde düşünüyorum. Socket.io/nodejs uygulamam için bir test çerçevesi kurmaya çalışıyorum. Bu tek sayfalık bir uygulama, yani test komut dosyalarımda ( Mocha kullanıyorum, ama bu gerçekten önemli değil) Sunucuyu başlatmak, ona karşı testler yapmak ve ardından sunucuyu kapatmak istiyorum. Test başlamadan önce sunucunun açıldığını varsayarak veya testlerden birinin sunucuyu başlatmasını sağlayarak ve sonraki her testin bunun bittiğini varsaymasını sağlayarak bunu aşabilirim, ama bu gerçekten karmaşık. Her test dosyasının uygun ayarlarla bir sunucu örneğini başlatmasını ve ardından testler bittiğinde bu örneği kapatmasını tercih ederim. Bu, testi çalıştırmanın garip bir bağımlılığı olmadığı ve her şeyin temiz olduğu anlamına gelir. Aynı zamanda başlatma / kapatma testi yapabileceğim anlamına geliyor.

Peki, bunun nasıl yapılacağına dair herhangi bir tavsiye? İstisnaları düşürmek için manuel olarak tetiklemeyi düşündüm, ancak bu karmaşık görünüyor. Express belgeleri ve kaynağı inceledim, ancak sunucuyu kapatacak herhangi bir yöntem bulamıyorum. Bunun için socket.io'da da bir şeyler olabilir, ancak soket sunucusu Express sunucusuna yeni eklendiğinden, bunun ekspres katmanda olması gerektiğini düşünüyorum.

Yanıtlar:


158

Ekspres sunucu artık düğüm http sunucusundan miras almadığı için işler değişti . Neyse ki app.listen sunucu örneğini döndürür.

var server = app.listen(3000);

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

23
Mocha testi durumunda, ('app') ihtiyacınız olduğunda, uygulama nesnesini genişletiyorum: app.server = app.listen (3000); bu yüzden daha sonra şunu söyleyebilirim: var app = required ('./ app'); app.server.close ();
Jack Chi

2
sunucuyu test ederken, github.com/visionmedia/supertest adresini ziyaret edin, gerçek sunucuyu başlatmadan test etmenizi sağlar
Lukas Liesis

Bunu server.close()bir kancadan ararsanız, yapılan geri aramayı da iletmenizi öneririm .
Ullauri

1
Not: Express Application örneği olan 'app' ile 'close' yöntemine sahip temeldeki yerel HTTP Sunucusu örneği olan 'app.listen'in dönüş değeri arasında büyük bir fark vardır. @JackChi yukarıda bunu ima etti.
ajxs

Bu, açık bırakılan açık istemci soketlerinde sorunlara neden olmaz mı?
Cameron Tacklind

20

Kullanın app.close(). Tam örnek:

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()Testler sona erdiğinde geri aramanın içinde arayın . Ancak, sürecin hala devam ettiğini unutmayın (artık dinlemese de).

Bundan sonra, işlemi bitirmeniz gerekiyorsa, arayın process.exit(0).

Bağlantılar:

app.close: http://nodejs.org/docs/latest/api/http.html#server.close (aynısı için de geçerlidir)

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


1
Mükemmel, tam olarak aradığım şey. Sanırım bunu Express'te bulamadım çünkü tam olarak anlayamadığım çekirdek düğüm http sunucusunu genişletiyorlardı. Teşekkürler!
drewww

Teşekkürler Srijan, bu da bana yardımcı oldu
Adam Hopkinson

Bu hala doğru mu? express.createServer, kullanımdan kaldırıldı olarak işaretlendi ve uygulamanın artık http.js sunucusundan devralmadığını söyleyen bir hata veriyor
Frank Schwieterman

4
Bu, ekspres 3'ten beri geçerli değil.
gprasant

4
Bir sunucuyu bu şekilde kapatmak için bir URL göstermek iyi bir fikir değildir IMHO.
shime

2

"Bir HTTP sunucusunun nasıl sonlandırılacağına" ilişkin bir varyasyonu birçok kez farklı destek kanalları. Ne yazık ki, mevcut kitaplıkların hiçbirini tavsiye edemedim çünkü bir şekilde eksikler . O zamandan beri, zarif HTTP sunucu sonlandırmasından beklenen tüm durumları ele alan (inanıyorum) bir paket oluşturdum.

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

Http-terminatörün ana yararı şudur:

  • Node.js API'ye maymun yaması yapmaz
  • ekli bir HTTP isteği olmadan tüm soketleri anında yok eder
  • devam eden HTTP istekleriyle soketlere zarif zaman aşımına izin verir
  • HTTPS bağlantılarını düzgün şekilde yönetir
  • Canlı tutma özelliğini kullanarak bağlantılara, bir bağlantı ayarlayarak sunucunun kapatıldığını bildirir: başlığı kapat
  • Node.js sürecini sonlandırmaz

Express.js ile kullanım:

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

const app = express();

const server = app.listen();

const httpTerminator = createHttpTerminator({
  server,
});

await httpTerminator.terminate();


-1

Sunucuyu başlatmak, testleri çalıştırmak ve sunucuyu durdurmak için bir bash betiği yazarak bunu kolayca yapabilirsiniz. Bu, tüm testlerinizi hızlı ve kolay bir şekilde çalıştırmak için o komut dosyasına takma ad vermenize izin verme avantajına sahiptir.

Bu tür komut dosyalarını tüm sürekli dağıtım sürecim için kullanıyorum. Bu konuda biraz fikir edinmek için Jon Rohan'ın Dead Simple Git Workflow'a bakmalısınız .


2
Bu işe yarardı, ancak mümkünse bash içermeyen bir çözümü tercih ederim. Belki aptalca bir tercihtir, ancak sunucuyu test bağlamından başlatmak / durdurmak istiyorum çünkü sunucu yapılandırmasına özgü testler + başlatma / kapatma testleri yazmayı kolaylaştırır. Ayrıca, sunucuyla ilgili testleri ayrı bir komut dosyası aracılığıyla çalıştırma zorunluluğunu getirmez.
drewww

Neden ortama özgü testler yazıyorsunuz? Belki yanılıyorum ama bu beni kötü bir uygulama olarak görüyor. Testlerinizin, geliştirme ortamlarından bağımsız olarak ekibinizin tamamında çalışmasını istediğiniz için, testlerinizle ortamdan bağımsız kalmaya çalışırım.
Josh Smith

Burada çevreye özgü bir şey yapmıyorum, sanmıyorum. Sunucu için (bir dosyadan yapılandırma seçeneklerini okuma, bir veri deposundan yükleme durumu, vb.), Diğer her şeyi test ettiğim aynı çerçevede test etmenin güzel olacağı bir avuç farklı başlangıç ​​seçeneği olacaktır. Ayrıca, örneğin, sunucuyu kapatan, tekrar açan ve işlem sırasında durumunu kaybetmediğinden emin olan testler yaptırmak istiyorum. Düğümden programlı olarak yapabilirsem, bash'de kod test etmekten daha kolaydır.
drewww

Test kodunuzu bash'ın kendisine yerleştiremezsiniz. Tıpkı kendi komut satırında yaptığınız gibi, sunucuyu başlatır ve testleri komut dosyasından çalıştırırsınız. Orada gerçekten özel bir sihir yok.
Josh Smith
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.