vitestquarkus-rest-client

Vitest fetch ECONNREFUSED ::1:9000 but works in browser url and the actual app


I am attempting to use Vitest to do some API testing of my Quarkus server (not mocking).

If I use a browser and the following url the request works. So the server is working. Also, my actual app can interact with the same server endpoint.

enter image description here

But when I make a simple Vitest test as follows and try the same endpoint using fetch I get the error below.

import { beforeAll, describe, expect, expectTypeOf, test } from 'vitest';

const BEFORE_ALL_TIMEOUT = 30000; // 30 sec

describe('Request Flowt test api', () => {
  let response;
  let body;

  beforeAll(async () => {
    response = await fetch(
      'http://localhost:9000/api/test',
    );
    body = await response.json();

  }, BEFORE_ALL_TIMEOUT);

  test('Should have response status 200', () => {
    expect(response.status).toBe(200);
  });
});

{ errno: -61, code: 'ECONNREFUSED', syscall: 'connect', address: '::1', port: 9000 }

If I use this example I found in a blog post, all tests pass and the console.log in the final test says: body[0].caption= This image was taken by NASA's EPIC camera onboard the NOAA DSCOVR spacecraft, so it is working.

import { beforeAll, describe, expect, expectTypeOf, test } from 'vitest';

const BEFORE_ALL_TIMEOUT = 30000; // 30 sec

describe('Request Earth Polychromatic Imaging Camera', () => {
  let response;
  let body;

  beforeAll(async () => {
    response = await fetch(
      'https://api.nasa.gov/EPIC/api/natural?api_key=DEMO_KEY',
    );
    body = await response.json();

  }, BEFORE_ALL_TIMEOUT);

  test('Should have response status 200', () => {
    expect(response.status).toBe(200);
  });

  test('Should have content-type', () => {
    expect(response.headers.get('Content-Type')).toBe('application/json');
  });

  test('Should have array in the body', () => {
    expectTypeOf(body).toBeArray();
  });

  test('The first item in array should contain EPIC in caption key', () => {
    console.log('body[0].caption=', body[0].caption)
    expect(body[0].caption).to.have.string('EPIC');
  });
});

What could be the issue using Vitest for my API when the API does work?

Thanks, Murray


Solution

  • Ok. The clue was in address: '::1' in the error message.

    localhost was being changed to ipv6 ::1 which is not what is being served!

    Changed to explicit ipv4 format and all works!

      beforeAll(async () => {
        response = await fetch(
    
          // 'http://localhost:9000/api/test' // <= NOPE
    
          'http://127.0.0.1:9000/api/test' // YES
        );
    
        body = await response.json();
    
      }, BEFORE_ALL_TIMEOUT);