Тестирование утечки памяти Jest Express Middleware - PullRequest
1 голос
/ 07 мая 2019

Я пытаюсь провести модульное тестирование своего промежуточного ПО для аутентификации для Express. Промежуточное программное обеспечение довольно просто и может быть просмотрено ниже полностью:

const admin = require('./../config/firebase/firebase');

// Models - User
const User = require('./../models/user');

const auth = async (req, res, next) => {
    try {
        // The Authorization Bearer Token sent in the header of the request needs to be decoded.
        const token = req.header('Authorization').replace('Bearer ', '');
        const decoded = await admin.auth().verifyIdToken(token);

        // Finding that user in the database by their Firebase UID.
        const user = await User.findOne({ _id: decoded.uid });

        // If that user does not exist, we'll throw an error.
        if (!user) {
            throw new Error();
        }

        // Making the user accessible to the endpoint.
        req.user = user;

        // Proceed
        next();
    } catch (e) {
        // HTTP 404 Unauthorized Response Status
        res.status(401).send({ error: 'Please authenticate.' });
    }
}

module.exports = auth;

Поскольку Firebase Admin SDK возвращает объект, который содержит UID пользователя в качестве свойства, для целей моих тестов я создаю «поддельный токен», который является просто объектом со свойством UID. Затем я высмеиваю Admin SDK так, чтобы он возвращал все, что было передано, например:

module.exports = {
    auth() {
        return this;
    },
    verifyIdToken(token) {
        return JSON.parse(token);
    },
    initializeApp(app) {
    },
    credential: {
        cert() {

        }
    }
}

Поскольку промежуточное ПО auth ожидает найти пользователя в тестовой базе данных, я должен настроить его как Jest Setup в beforeAll hook:

const userOneToken = JSON.stringify({ uid: 'example UID' });
const userOne = {
    _id: 'example UID',
    // ...
};

beforeAll(async () => {
    await User.deleteMany();
    await User.save(userOne);
    app.use(auth).get('/', (req, res) => res.send());
});

Это означает, что промежуточное ПО всегда сможет получить взамен UID, который можно использовать для поиска тестового пользователя в тестовой базе данных.

Сам набор тестов после импорта моего приложения Express довольно прост, всего три теста:

const auth = require('./../../src/middleware/auth');

describe('Express Auth Middleware', () => {
    test('Should return 401 with an invalid token', async () => {        
        await request(app)
            .get('/')
            .set('Authorization', 'Bearer 123')
            .send()
            .expect(401);   
    });

    test('Should return 401 without an Authorization Header', async () => {        
        await request(app)
            .get('/')
            .send()
            .expect(401);   
    });

    test('Should return 200 with a valid token', async () => {        
        await request(app)
            .get('/')
            .set('Authorization', `Bearer ${userOneToken}`)
            .send()
            .expect(200);   
    });
});

Однако, похоже, что тесты имеют утечку памяти (очевидно, если вызвать с флагом --detectLeaks). Кроме того, кажется, что Jest также находит открытую ручку, оставленную после последнего теста. Запуск пакета с флагом --detectOpenHandles возвращает ошибку TCPSERVERWRAP в запросе get последнего теста.

Потенциальные решения были предложены в этом выпуске GitHub , но ни одно из них не помогло мне.

Любая помощь в решении этой проблемы будет принята с благодарностью, потому что все мои тестовые наборы теряют память, потому что они полагаются на Supertest. Спасибо.

...