vercel / micro

Asynchronous HTTP microservices
MIT License
10.59k stars 459 forks source link

Test in the readme doesn't work #425

Closed kennetpostigo closed 4 years ago

kennetpostigo commented 4 years ago

The tests in the readme section "Testing" doesn't seem to work

const http = require('http')
const micro = require('micro')
const test = require('ava')
const listen = require('test-listen')
const request = require('request-promise')

test('my endpoint', async t => {
  const service = new http.Server(micro(async (req, res) => {
    micro.send(res, 200, {
      test: 'woot'
    })
  }))

  const url = await listen(service)
  const body = await request(url)

  t.deepEqual(JSON.parse(body).test, 'woot')
  service.close()
})

Is this still the recommended approach?

ndneighbor commented 4 years ago

Commenting to echo that I have this issue.

When I invoke the function with micro in my test, ava hangs. My function code that am testing

module.exports = (req, res) => {
  let who = "anonymous";

  if (req.body && req.query && req.query.who) {
    who = req.query.who;
  } else if (req.query && req.query.who) {
    who = req.query.who;
  } else if (req.cookies && req.cookies.who) {
    who = req.cookies.who;
  }

    res.send(res, 200, `Hello ${who}!`)
};

My test looks like the following

const test = require('ava');
const index = require('../api/index');
const micro = require("micro");
const http = require('http')
const listen = require('test-listen')
const request = require('request-promise')

test('my endpoint', async t => {
  const service = new http.Server(micro(index));

  const url = await listen(service)
  const body = await request(url)

  t.deepEqual(body, 'Hello anonymous!')
  service.close()
})

Now using res.write and res.end instead of res.send to illustrate that not using micro this works:

module.exports = (req, res) => {
  let who = "anonymous";

  if (req.body && req.query && req.query.who) {
    who = req.query.who;
  } else if (req.query && req.query.who) {
    who = req.query.who;
  } else if (req.cookies && req.cookies.who) {
    who = req.cookies.who;
  }

  res.write(`Hello ${who}!`);
  res.end();
};

Now testing a plain https.Server without using micro will pass my test

const test = require('ava');
const index = require('../api/index');
const micro = require("micro");
const http = require('http')
const listen = require('test-listen')
const request = require('request-promise')

test('my endpoint', async t => {
  const service = new http.Server(index);

  const url = await listen(service)
  const body = await request(url)

  t.deepEqual(body, 'Hello anonymous!')
  service.close()
})
dmaevac commented 4 years ago

I had the same issue and resolved it be removing the unnecessary(?) use of http.Server in the test. Im not sure if the micro code has been updated since that example test was written, or even if this is a valid solution - but it seems to work.

const micro = require('micro')
const listen = require('test-listen')
const request = require('request-promise')

test('route', async () => {
  const service = micro(async (req, res) => {
    micro.send(res, 200, {
      recieved: true
    })
  })
  const url = await listen(service)
  const body = await request(url)

  expect(JSON.parse(body).recieved).toEqual(true)
  service.close()
})
timneutkens commented 4 years ago

Moved the note about the readme being for the canary version: https://github.com/zeit/micro/commit/ceaf102e7e6177e4028fde48f52362791fda3fc1