How to test angular guards/resolvers without mocking ActivatedRouteSnapshot
Asked Answered
H

0

6

I'm trying to test an Angular Resolver which accesses children routes param.

My guard works fine but I cannot create an unit test easily because I cannot create an ActivatedRouteSnapshot with children routes (read only property).

My resolver

@Injectable({
    providedIn: 'root'
})
export class MyResolverGuard implements Resolve<string> {

    constructor() {
    }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): string {
        return route.firstChild.paramMap.get('my-param');
    }
}

My test :

    it('should resolve chilren route params', () => {
        guard = TestBed.get(MyResolverGuard);
        const route = new ActivatedRouteSnapshot();
        // Cannot assign children because it's a read only property
        route.children = [...];
        const myResolverParams = guard.resolve(route, null);
    });

Is there other any other ways than using mock ActivatedRouteSnapshot ?

Does my approach to test guard is good ?

Thanks for sharing your strategy.

Headset answered 19/7, 2019 at 7:52 Comment(5)
Could you explain why you want to test the guard without mocking the ActivatedRouteSnapshot?Besot
That's because I don't want bypass logic inside ActivatedRouteSnapshot. For exemple children routes will set firstChild property. My approach may be wrong, I just wanted to look for an alternative than mocking.Headset
Imho maybe it would be a better approach to test that inside an integration test rather than a unit test.Besot
If you want a populated ActivatedRouteSnapshot object, I think you would need to mock your routes too (with the Guard) and perform a router.navigate(). As you have noted, by mocking ActivatedRouteSnapshot object, you can't manipulate read-only properties. ActivatedRouteSnapshot represents a snapshot/state of an ActivatedRoute object at a point in time.Globule
By performing a router.navigate() to a mock route in RouterTestModule that is also defined with the Guard will allow the guard's injected ActivatedrouteSnapshot to have various read-only properties (i.e. firstChild, children, pathFromRoot) that would otherwise be null in a mocked new ActivatedRouteSnapshot() object. I have no idea how your guard works so I am not able to provide code samples. Do post more code example (like how your routes look like) if you think it would help people to understand your context and answer your question...Globule

© 2022 - 2024 — McMap. All rights reserved.