Angular2 RC5 Mock Activated Route Params
Solution 1
Your mock must reflect the object it's replacing. You .subscribe
because it returns an observable, not just the object, so your mock value should too:
import { Observable } from 'rxjs/Rx';
...
{ provide: ActivatedRoute, useValue: { 'params': Observable.from([{ 'id': 1 }]) } }
Solution 2
Answer given by @jonrsharpe allows you to mock params
, but those params would be the same in every test.
If you want to be able to change the params
, to set it at the start of a test, you can do it like this:
At the top:
describe('SomeComponent', () => {
(...)
let params: Subject<Params>;
(...)
in beforeEach
(the async
one - where you have imports
, providers
etc.):
beforeEach(async(() => {
params = new Subject<Params>();
(...)
in providers
:
(...)
{
provide: ActivatedRoute,
useValue: {
params: params
}
}
(...)
and then in test:
it('someTest', () => {
params.next({'id': '123'});
fixture.detectChanges();
(...)
IMPORTANT NOTE
Be sure to call fixture.detectChanges
after params.next
.
This means you should remove fixture.detectChanges
from beforeEach
and add it to every test.
GlacialFlames
Updated on June 12, 2022Comments
-
GlacialFlames almost 2 years
I need to be able to mock the activated route parameters to be able to test my component.
Here's my best attempt so far, but it doesn't work.
{ provide: ActivatedRoute, useValue: { params: [ { 'id': 1 } ] } },
The ActivatedRoute is used in the actual component like this:
this.route.params.subscribe(params => { this.stateId = +params['id']; this.stateService.getState(this.stateId).then(state => { this.state = state; }); });
The error I get with my current attempt is simply:
TypeError: undefined is not a constructor (evaluating 'this.route.params.subscribe')
Any help would be greatly appreciated.
-
Bhushan Gadekar over 7 yearsHi i was just wondering How can I use this provide activated route inside my it() block?
-
jonrsharpe over 7 years@BhushanGadekar what do you mean? It's just an object, you can assign the
useValue
to a name. -
Bhushan Gadekar over 7 years@jonsharpe can you edit your answer for it() block.. I have set pageId from route params, and i want to check if after ngOnInit() gets called, my pageId is populated or not?
-
jonrsharpe over 7 years@BhushanGadekar you literally just have to extract and name that object within your tests, actually only the inner
{ 'id': 1 }
. You really should be able to figure it out. -
Magnus Gudmundsson over 7 yearsThis almost works,.... I get cannot read property 'unsubscribe' of undefined. Probably because our Observable goes out of scope. Do you have a solution for that @jonrsharpe ? :)
-
jonrsharpe over 7 years@MagnusGud you've given nowhere near enough information to answer that, I don't even know what you're trying to unsubscribe from, or where.
-
Magnus Gudmundsson over 7 yearsSorry about that jon. I have the following scenario: in ngOnInit Im doing this: this.subscription = this.route.params.subscribe((params: any) => //and so on. and then in ngOnDestroy Im tearing down the subscription: this.subscription.unsubscribe(); what happens is that subscription is now undefined. I don't really get why. What im going to do is to make my code more robust, and check if subscription is undefined before tearing it down. Then it should work :)
-
jonrsharpe over 7 years@MagnusGud I don't know why either, that's probably unrelated to the mocking, as you're getting a real
Observable
. Once you have isolated the issue, ask a new question with a minimal reproducible example. -
vince almost 7 years@MagnusGud I have a feeling that you need to add a conditional to your
ngOnDestroy()
method. LikengOnDestroy() { if (this.sub) { this.sub.unsubscribe() } }
-
ismaestro about 4 yearsand if I'm using queryParams inside the snapshot?