Angular 6 Testing Jasmine Karma: Override Provider Not working

Viewed 5311

So i've looked at many issues online including this one https://github.com/angular/quickstart/issues/320 and i'm stumped...

How I have my code set up is that I have my main describe create my testbed component, Here I have my mockParams set up for the active route so we can this.route.queryparams.subscribe(..), My problem is I am unable to overwrite the values in a different describe or 'it' block.

 beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MyComponent],
      imports: [RouterTestingModule
        })],
      providers: [
        { provide: ActivatedRoute, useValue: mockParams },
      ],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents();
}));

Here is an example of me adding a the override in a different NESTED describe block...

beforeEach(() => {
      TestBed.overrideProvider(ActivatedRoute, 
      {useValue: newMockParams});
      TestBed.compileComponents();
      fixture = TestBed.createComponent(MyComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
});

It's almost like this doesnt run at all... the new mock params do not change if i re-use mockParams and change the values then it will change the value in the original describe, Do I really have to re-create my component in every nested describe? It just doesn't feel right that I would have to do so when the only thing I need to change is the provider, i'm unsure what overrideProvider even does at this point! Any help would be greatly appreciated!

1 Answers

Updated with new information provided in comments below.

My suggestion is to change the value returned by route.queryParams. You mentioned in the comments that your ngOnInit() function looks like this:

ngOnInit() {
    this.route.queryParams.subscribe(params => { this.value = params; });
}

If you change the return value from the queryParams observable before running .detectChanges() in each test, this should achieve what you want. For example, something like this:

describe('MyComponent', () => {
    let mockActivatedRoute = {queryParams: of({old: 'test'})};
    let component: MyComponent;
    let fixture: ComponentFixture<MyComponent>;
    let route: ActivatedRoute;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [MyComponent],
            imports: [ ],
            providers: [
                { provide: ActivatedRoute, useValue: mockActivatedRoute },
            ]
        })
        .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(MyComponent);
        component = fixture.componentInstance;
        route = TestBed.get(ActivatedRoute);
    });

    it('ngOnInit should initialize and route params be intial values', () => {
        fixture.detectChanges(); // execute ngOnInit() in component
        expect(component.value).toEqual({old: 'test'}); // check that value is correct
    });
        it('ngOnInit should initialize and route params be changed values', () => {
        route.queryParams = of({new: 'newTest'/* mocked params */});
        fixture.detectChanges();
        expect(component.value).toEqual({new: 'newTest'}); // check that value is correct
    });
});

I tested this all in a stackblitz to be sure this all works error free. :) Here is the link: STACKBLITZ

Related