ZijianHe / koa-router

Router middleware for koa.
MIT License
4.85k stars 406 forks source link

Cannot run the same routes in 2 different tests #311

Open dagda1 opened 7 years ago

dagda1 commented 7 years ago

I have this test:

import Koa from 'koa';
import Router from 'koa-router';
import http from 'http';
import request from 'supertest-as-promised';
import adminRoutes from '../../../routes/Admin';
import Result from '../../../models/result';
import Promise from 'bluebird';
import { assert, expect } from 'chai';
import { getResults } from '../../../controllers/Results';

import mockKnex from 'mock-knex';

const tracker = mockKnex.getTracker();

context('admin/results routes', () =>{
  describe('successful GET /admin/results', () => {
    let response,
        server;

    before(async () => {
      const app = new Koa();

      const router = new Router();

      router.use('/admin', adminRoutes.routes());

      app.use(router.routes());

      server = http.createServer(app.callback());

      response = await request(server)
        .get('/admin/results');
    });

    after(() => {
      server.close();
    });

    it('returns results', async () => {

      expect(response.body.length).to.equal(1);
    });
  });
})

And I have this test:

'use strict';

import Koa from 'koa';
import Router from 'koa-router';
import http from 'http';
import request from 'supertest-as-promised';
import adminRoutes from '../../routes/Admin.js';
import Result from '../../models/result';
import Promise from 'bluebird';
import { assert, expect } from 'chai';
import { getResults } from '../../controllers/Results';
import TokenAuth from '../../middleware/TokenAuth';

import mockKnex from 'mock-knex';

const tracker = mockKnex.getTracker();

context('TokenAuth middleware', () =>{
  describe('GET /admin/ping without token', () => {
    let response,
        server;

    before(async () => {
      const app = new Koa();

      const router = new Router();

      router
        .use(TokenAuth)
        .use('/admin', adminRoutes.routes());

      app.use(router.routes());

      server = http.createServer(app.callback());

      response = await request(server)
        .get('/admin/ping');
    });

    after(() => {
      server.close();
    });

    it('should return a 401 unauthorized response', () => {
      expect(response.status).to.equal(401);
    });
  });
})

If I comment out either test 1 or test 2 then the uncommented test will pass.

If I have them both uncommented then then the test that runs second will give 404s for the request to any routes defined in the adminRoutes routes that I have created.

What am I doing wrong? Is there some cleanup code that I should be using?

dagda1 commented 7 years ago

would it be possible to get some advice with this?

jbielick commented 7 years ago

Routers are mutable and it looks like adminRoutes is being shared between test cases. I suspect this is related to a bug about the mutability of routers #244. The only thing I can suggest is making your adminRoutes module a factory and returning a new router from that factory for each use-case.