Home > other >  NestJs - test on response from interceptor
NestJs - test on response from interceptor

Time:10-16

I have a simple interceptor that deletes a field from response:

import {
    CallHandler,
    ExecutionContext,
    Injectable,
    NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

export interface Response<T> {
    data: T;
}

@Injectable()
export class Transform<T> implements NestInterceptor<T, Response<T>> {
    intercept(
        context: ExecutionContext,
        next: CallHandler,
    ): Observable<Response<T>> {
        return next.handle().pipe(
            map((response) => {
                delete response?.value?.name;
                return response;
            }),
        );
    }
}

How can I write test case for this? Basically, I wanted to test if 'name' is deleted from response. I wrote the following test case but response is coming as undefined:

  it('should delete `name` from response if present', async () => {
    transformInterceptor = new TransformRepoResponse();
    const context = {
      switchToHttp: () => ({
        getRequest: () => jest.fn(),
      }),
    };
    const next = {
      handle: jest.fn().mockReturnValue({
        pipe: jest.fn(),
      }),
    };
    requestMock.method = 'GET';
    const response = await transformInterceptor.intercept(context, next);
    expect(response.value.name).toBe(undefined);
  });

CodePudding user response:

Interceptors aren't async so you can't await their response without using lastValueFrom() as a wrapper. Also, your next.handle() should return an observable that will be acted on by the .pipe. Something like

it('should delete `name` from response if present', (done) => {
    transformInterceptor = new TransformRepoResponse();
    const context = {
      switchToHttp: () => ({
        getRequest: () => jest.fn(),
      }),
    };
    const next = {
      handle: jest.fn().mockReturnValue(of({
        value: {
          name: 'name-field',
          foo: 'foo-field',
        }
      }),
    };
    requestMock.method = 'GET';
    transformInterceptor.intercept(context, next).subscribe({
      next: (data) => {
        expect(data).toEqual({
          value: { foo: 'foo-field' }
        })
      complete: done
      }
    })
  });

Now you're testing the interceptor as an observable, you only expect one value so using the next of subscribe is fine, and you're telling Jest that the test is finished when the observable completes.

  • Related