angular - Vad är skillnaden mellan TestBed.get och new Service(...dependencies)
Den angular-guiden visar två olika sätt att testa, ett genom att anropa new Service() och tillhandahålla beroenden till konstruktören direkt, och det andra genom att använda beroendeinjektion genom att anropa TestBed.get(Service).
Båda dessa verkar funktionellt identiska för mig, förutom när jag anropar TestBed.get() i följd så anropas inte konstruktorn efter det första anropet.
Angular-dokumentationen nämner också att TestBed.get() är föråldrad (även om guiden fortfarande refererar till den!) och att jag bör använda Type eller InjectionToken istället, men jag ser inte hur någon av dessa klasser skulle kunna ersätta TestBed.get().
Svar #1
Föråldrad från v9.0.0, använd TestBed.inject
get(token: any, notFoundValue?: any): any
Se hur vi kan injicera nu:
describe('MyAmountComponent', () => {
let component: MyAmountComponent;
let fixture: ComponentFixture<MyAmountComponent>;
let productService: ProductService;
let orderService: OrderService;
beforeEach(() => {
TestBed.configureTestingModule({
.....
})
.compileComponents();
productService = TestBed.inject(ProductService);
orderService = TestBed.inject(OrderService);
});
Bara lägger till så att det kanske kan hjälpa någon.
Svar #2
När du anropar TestBed.configureTestingModule({ providers: [SomeService] });, ställer detta upp ett NgModule som kan användas i efterföljande tester. Om du anropar TestBed.get(SomeService), hämtar detta SomeService från injektorn och instansierar det om det behövs. Om det instansieras, injicerar injektorn referenser till dess beroenden och returnerar en ny instans av tjänsten.
Om SomeService redan har instansierats, som i ditt fall, behöver TestBed inte skapa det. Detta innebär att det inte kommer att anropa konstruktorn en efterföljande gång.
För att svara på din fråga om skillnaden, i princip är de samma om du mockar alla dina beroenden och om du inte behöver åtkomst till DOM:en. Att instansiera klasser utan TestBed är betydligt snabbare eftersom det inte finns någon overhead av att ladda beroendeinjizieren för varje test.
När det gäller att TestBed.get() är föråldrad, i Angular 8.0.0, var det endast den specifika överlagringen som tillåter vilken typ som helst som var föråldrad (se https://github.com/angular/angular/blob/master/packages/core/testing/src/test_bed.ts#L67). Istället för get(token: any, notFoundValue?: any): any; ändrades signaturen till get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any; vilket betyder att du var tvungen att använda en klassreferens eller en injection-token. Inga strängar eller andra saker för att referera till något i injektorn.
I Angular 9.0.0 kommer TestBed.get()-metoden att vara helt föråldrad och du behöver använda TestBed.inject istället. Se https://github.com/angular/angular/blob/master/packages/core/testing/src/test_bed.ts#L65
