jordanpowell88 / angular-ct

Angular Component Testing
19 stars 2 forks source link

Providers should be set at component level #37

Closed yjaaidi closed 2 years ago

yjaaidi commented 2 years ago

When users set providers using the mount function, these providers should not be set at the TestBed module level but at the component level using the TestBed.overrideComponent function, somewhat like this TestBed.overrideComponent(componentType, {add: {providers}}) function.

It should be add and not set because the last added provider will overwrite the previous ones if it's the same injection token or class.

jordanpowell88 commented 2 years ago

@yjaaidi can you explain "why" this is necessary? I'm trying to understand the use-case.

In my example I have an OvveridesComponent which sets a provider in it's Decorator and then mounting does NOT require any providers for it work.

However, in a case where the component is provided a Service from it's module it would fail in this case because it is expecting to receive the provider from the TestBed Module as well. Am I missing something?

yjaaidi commented 2 years ago

Typically, when testing the OverridesComponent, you might want to override the provider and pass a test double that behaves differently, causing errors or simply returning a static value etc...

mount(OverridesComponent, {
  providers: [
    {
      provide: MyService
      useValue: {
        tick$: of(42), // or throwError(new Error('💥')) or a Subject so we can emit new values and see how the component behaves
      } as MyService
    }
  ]
})

Cf. https://github.com/yjaaidi/angular-ct/blob/8b7564ea716d272a62922c84cf662229aaaf149b/src/app/count/overrides/overrides.component.cy.ts#L11

However, in a case where the component is provided a Service from its module it would fail in this case because it is expecting to receive the provider from the TestBed Module as well. Am I missing something?

No, because the test double provided at the component level will shadow the module service and take precedence which is what we want.

Does this make any sense?