I have a component, which has two dependencies: one is LOCALE_ID
defined globally in angular, another is language, defined in the Component as { provide: LANGUAGE_TOKEN, useValue: navigator.language }
For testing, I am both overriding them in TestBed for all tests, so tests don't get anything injected from the Chrome browser doing the karma tests, and tests don't have different result based on testing environment:
TestBed.configureTestingModule({
declarations: [
MyComponent, RouterStubComponent,
],
imports: [
MatToolbarModule, RouterTestingModule, MatIconModule, MatButtonModule,
],
providers: [
{provide: LOCALE_ID, useValue: 'en-US' },
]
}).compileComponents();
TestBed.overrideProvider(LOCATION_TOKEN, {useValue: locationStub});
TestBed.overrideProvider(LANGUAGE_TOKEN, {useValue: 'en-US' });
Now I have some logic in the component that depends on locale and browser language, so I need to mock them. Mocking LANGUAGE_TOKEN
was super easy, barely an inconvenience:
it('should redirect to spanish when in spanish browser', () => {
TestBed.overrideProvider(LANGUAGE_TOKEN, {useValue: 'es'});
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
expect(hrefSpy.calls.count()).toBe(1);
expect(hrefSpy.calls.argsFor(0)[0]).toEqual(environment.spanUrl);
});
However override LOCALE_ID
with same code doesn't work.
it('should ...', () => {
TestBed.overrideProvider(LOCALE_ID, {useValue: 'es-ES'});
console.log(TestBed.get(LOCALE_ID)); // en-US!!!!
fixture = TestBed.createComponent(MamanComponent);
component = fixture.componentInstance;
fixture.detectChanges();
expect(hrefSpy.calls.count()).toBe(1); //FAIL
expect(hrefSpy.calls.argsFor(0)[0]).toEqual(environment.engUrl);//FAIL
});
I was unable to find a working answer in this question either.
To override a provider you need to call the Provider. override() method. This method receives a single argument called overriding . If the overriding value is a provider, this provider is called instead of the original.
TestBed.get() was deprecated as of Angular version 9. To help minimize breaking changes, Angular introduces a new function called TestBed.inject() , which you should use instead.
TestBed is used to configure and initialize the environment unit tests. The describe code block represents the test suite for AppComponent. It contains specs and additional code that's used for testing AppComponent. beforeEach is a global function in Jasmine that runs some setup code before each spec in the test suite.
TestBed. createComponent() creates an instance of the BannerComponent , adds a corresponding element to the test-runner DOM, and returns a ComponentFixture . Do not re-configure TestBed after calling createComponent .
This is because as soon as you call compileComponents
, the providers are frozen and won't be overridden.
Either remove LOCALE_ID
from the providers
so that it's value is not frozen. (But make sure to provide it using overrideProviders
before creating the component instance):
TestBed.configureTestingModule({
declarations: [
MyComponent, RouterStubComponent,
],
imports: [
MatToolbarModule, RouterTestingModule, MatIconModule, MatButtonModule,
],
providers: [
--> remove
]
}).compileComponents();
TestBed.overrideProvider(LOCALE_ID, {useValue: 'es-ES'});
//Add it before creating component, to have a default value in each test, add it in a beforeEach block.
Or you can call compileComponents
before creating component instance in each test:
TestBed.configureTestingModule({
declarations: [
MyComponent, RouterStubComponent,
],
imports: [
MatToolbarModule, RouterTestingModule, MatIconModule, MatButtonModule,
],
providers: [
{provide: LOCALE_ID, useValue: 'en-US' },
]
});
--> remove compileComponents
Then in every test :
it('should ...', () => {
TestBed.overrideProvider(LOCALE_ID, {useValue: 'es-ES'});
// Add here
TestBed.compileComponents();
fixture = TestBed.createComponent(MamanComponent);
component = fixture.componentInstance;
fixture.detectChanges();
expect(hrefSpy.calls.count()).toBe(1); //FAIL
expect(hrefSpy.calls.argsFor(0)[0]).toEqual(environment.engUrl);//FAIL
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With