angularngrxngrx-signal-store

Angular mocked signalStore test raises null pointer when it asks for its dependencies


I'm doing a test of a component that uses a signalStore

signalStore:

export const TemplateStore = signalStore(
  { providedIn: 'root' },
  withState(initialState),
  withMethods(
    (
      store,
      templateService = inject(TemplatesService)
    )

Component:

@Component({
  selector: 'app-template-list-layout',
  standalone: true,
  providers: [TemplateStore],
  templateUrl: './template-list-layout.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TemplateListLayoutComponent {
  templateStore = inject(TemplateStore);

My test:

beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [TemplateListLayoutComponent],
      providers: [
        {
          provide: TemplateStore,
          useValue: {
            filterTemplates: () => {},
            sortTemplates: () => {},
          },
        },
      ],
    }).compileComponents();

    fixture = TestBed.createComponent(TemplateListLayoutComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

When I run the test this message is the error:

NullInjectorError: R3InjectorError(Standalone[TemplateListLayoutComponent])[TemplatesService -> TemplatesService -> HttpClient -> HttpClient]: NullInjectorError: No provider for HttpClient!

Why I'm getting this error if I am mocking it?

I've tried different approaches but it doesnt work either... instead of using useValue I tried useClass and the same result.


Solution

  • The problem was I was declaring the TemplateStore as a provider in the component annotation. Just removed it and the test worked as expected.

    @Component({
      selector: 'app-template-list-layout',
      standalone: true,
      providers: [/* REMOVED TEMPLATE STORE */],
      templateUrl: './template-list-layout.component.html',
      changeDetection: ChangeDetectionStrategy.OnPush,
    })
    export class TemplateListLayoutComponent {
      templateStore = inject(TemplateStore);