Skip to content

Commit

Permalink
fix: possibility to override global services in Angular component tes…
Browse files Browse the repository at this point in the history
…ts (#24394)

* fix: allow to override global services in Angular component tests

* move DI tests into their own context

* exclude `componentProviders` when a component is mounted with a template

* - revert and remove `componentProviders`
- run `eslint --fix` on `mount.cy.ts`
- add tests that use `TestBed.inject`

Co-authored-by: Zachary Williams <ZachJW34@gmail.com>
  • Loading branch information
rainerhahnekamp and ZachJW34 committed Oct 31, 2022
1 parent 58e0ab9 commit 54d2853
Show file tree
Hide file tree
Showing 5 changed files with 285 additions and 140 deletions.
12 changes: 1 addition & 11 deletions npm/angular/src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,22 +163,12 @@ function initTestBed<T> (
component: Type<T> | string,
config: MountConfig<T>,
): Type<T> {
const { providers, ...configRest } = config

const componentFixture = createComponentFixture(component) as Type<T>

getTestBed().configureTestingModule({
...bootstrapModule(componentFixture, configRest),
...bootstrapModule(componentFixture, config),
})

if (providers != null) {
getTestBed().overrideComponent(componentFixture, {
add: {
providers,
},
})
}

return componentFixture
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Component, Injectable } from '@angular/core'

@Injectable({ providedIn: 'root' })
export class Cart {
#items: string[] = []

add (product: string) {
this.#items.push(product)
}

getItems () {
return this.#items
}
}

@Component({
template: `<div><h2>Great Product</h2><button (click)="buy()" data-testid="btn-buy">Buy</button></div>`,
})
export class ProductComponent {
constructor (private cart: Cart) {
}

buy () {
this.cart.add('Great Product')
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Component, Injectable } from '@angular/core'

@Injectable({ providedIn: 'root' })
export class MessageService {
get message () {
return 'globally provided service'
}
}

@Component({
template: `<p>{{messageService.message}}</p>`,
providers: [{
provide: MessageService,
useValue: { message: 'component provided service' },
}],
})
export class ComponentProviderComponent {
constructor (public messageService: MessageService) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Component, Injectable } from '@angular/core'

@Injectable({ providedIn: 'root' })
export class TransientService {
get message () {
return 'Original Transient Service'
}
}

@Injectable({ providedIn: 'root' })
class DirectService {
constructor (private transientService: TransientService) {
}

get message () {
return this.transientService.message
}
}

@Component({
template: `<p>{{directService.message}}</p>`,
})
export class TransientServicesComponent {
constructor (public directService: DirectService) {}
}

0 comments on commit 54d2853

Please sign in to comment.