Как протестировать веб-сокеты (шлюзы), содержащие фильтры исключений, в тестировании e2e - PullRequest
0 голосов
/ 27 сентября 2018

Проблема

Кажется, что фильтры исключений вообще не используются при тестировании E2E на шлюзе

Код

some-gateway.e2e-spec.ts

import { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';

import { AppModule } from '@/app.module';
import { SomeGateway } from './some.gateway';

describe('SomeGateway', () => {
    let app: INestApplication;
    let someGateway: SomeGateway;
    const mockClient = {
        emit: jest.fn(),
    };

    beforeAll(async () => {
        const moduleFixture = await Test.createTestingModule({
            imports: [AppModule],
        }).compile();

        app = moduleFixture.createNestApplication();
        await app.init();

        someGateway = app.get(SomeGateway);
    });

    afterAll(async () => {
        await app.close();
    });

    beforeEach(() => {
        jest.resetAllMocks();
    });

    describe('someEventListener', () => {
        it('does not throw an exception because I have a exception filter', async (done) => {

            await someGateway.someEventListener(
                mockClient
            );

            expect(mockClient.emit).toHaveBeenCalled();
            done();
        });
    });
});

some-gateway.ts

import { SomeExceptionFilter } from './some-exception-filter';
import { UseFilters } from '@nestjs/common';
import {
    SubscribeMessage,
    WebSocketGateway,
} from '@nestjs/websockets';

@UseFilters(new SomeExceptionFilter())
@WebSocketGateway({ namespace: 'some-namespace' })
export class SomeGateway {

    @SubscribeMessage('some-event')
    async someEventListener(client): Promise<void> {
        throw new Error();
    }
}

some-exception-filter.ts

import { ArgumentsHost, Catch } from '@nestjs/common';

@Catch()
export class SomeExceptionFilter {
    catch(exception: any, host: ArgumentsHost) {
        console.log('i should be called :(');

        const client = host.switchToWs().getClient();

        client.emit('exception', { message: 'not ok' });
    }
}

Некоторые мысли

возможно, мне стоит использоватьapp.getHttpServer() чтобы можно было заставить его работать, но как имитировать соединение socket.io с помощью supertest?

1 Ответ

0 голосов
/ 27 сентября 2018

Мне удалось провести реальное тестирование e2e с реальным клиентом socket.io:

ws-client.helper.ts

import * as io from 'socket.io-client';
import {INestApplication} from "@nestjs/common";

export const getClientWebsocketForAppAndNamespace = (app: INestApplication, namespace: string, query?: object) => {
    const httpServer = app.getHttpServer();
    if (!httpServer.address()) {
        httpServer.listen(0);
    }

    return io(`http://127.0.0.1:${httpServer.address().port}/${namespace}`, { query });
};

some-gateway.e2e-spec.ts

...

describe('someEventListener', () => {
    it('does not throw an exception because I have a exception filter', (done) => {

        const socket = getClientWebsocketForAppAndNamespace(app, 'some-namespace');

        socket.on('connect', () => {
            socket.emit('some-event');
        });

        socket.on('exception', (exception) => {
            expect(exception).toEqual({
                message: 'not ok',
            });

            socket.close();
            done();
        });

    });
});

...
...