如何在e2e测试中测试包含异常过滤器的websocket(网关)

时间:2018-09-27 11:38:05

标签: typescript testing socket.io jestjs nestjs

问题

在网关上进行端到端测试时,似乎根本没有使用异常过滤器

代码

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()使其能够工作,但是如何使用supertest模拟socket.io连接?

1 个答案:

答案 0 :(得分:1)

我已经设法使用真正的socket.io客户端进行了真正的e2e测试:

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();
        });

    });
});

...