Search code examples
angularts-jestangular-test

Angular Testing Pipe that depends on Pipe (inject() must be called from an injection context)


I'm having trouble with a test in Angular (using jest) for a pipe that depends on the DatePipe. The error I'm getting is:

NG0203: inject() must be called from an injection context such as a constructor,
a factory function, a field initializer, or a function used with `runInInjectionContext`.
Find more at https://angular.io/errors/NG0203

But it is complaining about a field initializer:

enter image description here

This is my pipe:

import { DatePipe } from '@angular/common';
import { Pipe, PipeTransform, inject } from '@angular/core';
import { FieldValue, Timestamp } from '@angular/fire/firestore';

@Pipe({
  name: 'timestampDate',
  standalone: true,
})
export class TimestampDatePipe implements PipeTransform {
  private readonly _datePipe = inject(DatePipe);

  transform(
    timestamp: FieldValue | Timestamp | undefined | null
  ): string | null {
    if (!timestamp) return '...';
    if (timestamp instanceof Timestamp)
      return this._datePipe.transform(timestamp.toDate(), 'short');
    else throw new Error('Timestamp must be an instance of Timestamp');
  }
}

And this is my spec:

import { DatePipe } from '@angular/common';
import { TestBed } from '@angular/core/testing';
import { TimestampDatePipe } from './timestamp-date.pipe';

describe('TimestampDatePipe', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [DatePipe],
    });
  });

  it('create an instance', () => {
    const pipe = new TimestampDatePipe();
    expect(pipe).toBeTruthy();
  });
});

I have the rudimentary understanding that I can use the inject function during what I call "constructor time." This is what I'm doing because it is being used in a field initializer, which the error is telling me to do. Does anyone know what I'm doing wrong? Thanks in advance!

note

I'm not sure its worth mentioning, but this pipe is located in a separate library in a nx workspace.

update

If I use DI via the constructor parameter for the DatePipe, and construct my outer pipe, in the test, with

const pipe = new TimestampDatePipe(TestBed.inject(DatePipe));

the error seems to go away. Is this a bug?


Solution

  • This is not a bug, when you instantiate your pipe manually you're not in an injection context.

    To fix the issue you can ask the TestBed to create the pipe for you :

    const pipe = TestBed.inject(TimestampDatePipe)