Angular spectator testing: target component-level service

648 Views Asked by At

In my Angular app I have a service which is provided at a component level:

@Component({
  selector: 'my-component',
  templateUrl: './my.component.html',
  providers: [MyService],
})
export class MyComponent implements OnInit, OnDestroy { ... }

I'm using spectator in my Angular tests and I'm trying to test the component providing the service in the following way:

const createComponent = createComponentFactory({
  component: MyComponent,
  providers: [
    // ... other services ...
    mockProvider(MyService),
  ],
  // ...
});

// ...

const spectator = createComponent();

const myService = spectator.inject(MyService);

But whenever I try to mock stuff on myService it does not work: it seems that it is getting a global instance of MyService instead of the component-level instance of MyService.

1

There are 1 best solutions below

0
Francesco Borzi On

There are two important steps to take when dealing with component-level provided services in testing.

1) Provide them at component-level in the test

Replace:

const createComponent = createComponentFactory({
  component: MyComponent,
  providers: [
    // ... other services ...
    mockProvider(MyService),
  ],
  // ...
});

// ...

const spectator = createComponent();

With:

const createComponent = createComponentFactory({
  component: MyComponent,
  providers: [
    // ... other services ...
  ],
  // ...
});

// ...

const spectator = createComponent({
  mockProvider(MyService),
});

Note that the provider is no longer specified in the createComponentFactory but in createComponent instead.

2) Get them from the component injector instead of the global one

The spectator.inject() method takes an optional second parameter called fromComponentInjector (that is boolean).

Replace:

const myService = spectator.inject(MyService);

With:

const myService = spectator.inject(MyService, true);