javascript - supertest eșuează cu ECONNRESET
Lucrez la un proiect Node.js și încerc să scriu cazuri de testare pentru aplicație. Endpoint-urile funcționează perfect atunci când le rulez în Postman. Dar când rulez cazurile de testare, unele dintre ele (de obicei primul din ordine) eșuează cu eroarea
- Error: read ECONNRESET
Am încercat să fac debugging, am căutat o soluție posibilă, dar nu reușesc să o repar. Lucrez cu jasmine/supertest pentru prima dată. Poate că lipsesc ceva ce nu pot anticipa, dar nu am reușit să aflu problema. Poate cineva mă poate ajuta cu asta? Mulțumesc mult anticipat.
Iată codul meu de test.
it('Gets Users List', async() => {
const response = await request.get('/users')
expect(response.status).toBe(200);
})
și funcția mea Controller
export const index = async (req:Request, res: Response) => {
try {
const users : DataObject = await model.index()
res.status(users.status);
res.json(users.data);
} catch (error) {
res.status(NOT_FOUND);
res.json(error);
}
}
Comportamentul ciudat pe care l-am observat este că atunci când adaug o altă metodă înaintea acesteia, atunci această metodă funcționează bine și prima returnează aceeași eroare. Presupun că primul apel este respins din cauza faptului că conexiunea nu a fost încă stabilită? Totuși, nu sunt sigur.
Cineva familiarizat cu această problemă?
Mulțumesc anticipat.
Răspuns #1
Astfel încât alții să poată beneficia, în comentarii @rwheadon a menționat că pentru ei a fost o condiție de cursă.
Pot confirma că a fost cazul și pentru noi.
Acesta este codul final funcțional pentru noi:
it('should fail without a valid token', (done) => {
// After multiple hours of trying to get it to work, we figured out that
// _in this specific test_, the file being consumed on the same tick as
// the request being sent causes an issue where the server has an
// ECONNRESET error. This is not an issue normally, or in any other
// test, only for this test.
const file = fs.createReadStream(path.join(process.cwd(), uploadExcelFile));
setTimeout(() => {
localSuperTest
.post(`/upload-redeem-codes`)
.attach('file', file)
.expect(401)
.end((err: any, res: any) => {
if (err) {
return done(err);
}
assert.equal(res.body.message, 'not authorized');
done();
});
});
});
Cumva, există o condiție de concurență în teste atunci când se folosește .attach() cu supertest.
Punctul principal, credem noi, este că citirea fișierului și apoi consumarea fișierului (cu .attach('file', file)) trebuie să aibă loc în două ticuri diferite în bucla de callback.
Sper că asta va salva o sărmană persoană de câteva ore de investigații.
Răspunsul #2
Pentru mine, setTimeout nu a funcționat. În cazul meu s-a rezolvat prin crearea unui nou agent http și adăugarea acestuia la cerere.
it('Should return status 400 when file type is not .docx', async () => {
try {
// Explicit socket timeout
const agent = new http.Agent({
keepAlive: true,
maxSockets: Infinity,
timeout: 10000
});
const response = await request(app)
.post('/api/preprocess')
.type('form')
.attach('file', jsonFilePath, 'data.json')
.field('data', JSON.stringify(data))
.field('startDelimiter', '<')
.field('endDelimiter', '>')
.agent(agent)
.expect(400);
expect(response.body.message).toBe('Wrong file type');
expect(response.body.errorCode).toBe(102);
} catch (error) {
Logger.warn('Comprehensive error details:', {
errorName: error.name,
errorMessage: error.message,
errorStack: error.stack,
errorProperties: error.properties
});
throw error;
}
});
Aceasta este soluția despre cum a funcționat pentru mine.
