7

I am writing the simplest component that is using a routeLink:

@Component({
    selector: 'memorySnippet',
    templateUrl: '<div class="memory-snippet-wrapper" *ngIf="memory" 
                  [routerLink]="['MainPanel', 'MemoryPanel', {'id' : this.memory.id}]">',
    directives: [CORE_DIRECTIVES, ROUTER_DIRECTIVES]
})
export class MemorySnippetComponent {
    @Input() memory: Memory;
}

The problem occurs when I try testing this component. The moment I add the router link Karma is complaining about missing providers:

After adding all the providers Karma is asking I get this:

beforeEachProviders(() => [
    MemorySnippetComponent,
    MEMORY_SERVICE_PROVIDERS,
    ROUTER_PROVIDERS,
    ApplicationRef
]);

But when I run the test I get this error:

EXCEPTION: EXCEPTION: Error during instantiation of Token RouterPrimaryComponent! (RouterLink -> Router -> RouteRegistry -> Token RouterPrimaryComponent).

ORIGINAL EXCEPTION: unimplemented

ORIGINAL STACKTRACE: Error: unimplemented

What am I doing wrong??? Is Angular 2 (2.0.0-beta.1) just not ready for testing components with router directives?

Community
  • 1
  • 1
Tomer Almog
  • 3,604
  • 3
  • 30
  • 36
  • That would be my interpretation of this error. It is still in beta, and testing guides haven't been released for this kind of testing. Perhaps you could find the RouterPrimaryComponent in the source and implement the interface then use `provide(RouterPrimaryComponent, {useClass: MyRouterPrimaryComponent})` to override it and perhaps get your testing working. – SnareChops Feb 01 '16 at 20:42
  • check the repo with the testing seed from the Angular team -> https://github.com/juliemr/ng2-test-seed its from this talk https://www.youtube.com/watch?v=C0F2E-PRm44 – Angular University Feb 01 '16 at 21:08
  • Doesn't that syntax need a return? `beforeEachProviders(() => { return [ MemorySnippetComponent, MEMORY_SERVICE_PROVIDERS, ROUTER_PROVIDERS, ApplicationRef ]}); – Todd W Crone Feb 01 '16 at 21:32

2 Answers2

9

You should have a beforeEachProviders method looking like:

import {MockApplicationRef} from '@angular/core/testing';

beforeEachProviders(() => [
  ROUTER_PROVIDERS,
  provide(APP_BASE_HREF, {useValue: '/'}),
  provide(ROUTER_PRIMARY_COMPONENT, {useValue: YourComponent}),
  provide(ApplicationRef, {useClass: MockApplicationRef}
]);

MockApplicationRef is provided by the framework for this kind of tests.

Sebas
  • 21,192
  • 9
  • 55
  • 109
cexbrayat
  • 17,772
  • 4
  • 27
  • 22
  • Thank you @cexbrayat, that worked! can you please point to the source of such documentation? – Tomer Almog Feb 01 '16 at 23:01
  • That's a unit test from my ebook ^^ books.ninja-squad.com. But I think I found it in the framework source code AFAIR. – cexbrayat Feb 01 '16 at 23:04
  • @TomerAlmog I am getting similar issue. Can you share the code how you fixed it? – abhinavmsra Apr 15 '16 at 08:23
  • The code above did fix it. I used another source when I had to test components with router dependencies. I found it in ngBook2 where they show how to create a mockRouter. it is very long, but if you need I will share it here. – Tomer Almog Apr 15 '16 at 16:48
5

For RC4 with new router now use ...

beforeEach(() => addProviders([
  APP_ROUTER_PROVIDERS, // must be first
  {provide: APP_BASE_HREF, useValue: '/'}, // must be second
  {provide: ActivatedRoute, useClass: Mock},
  {provide: Router, useClass: Mock}
]));

A github project using this approach is ...

https://github.com/danday74/angular2-coverage

danday74
  • 52,471
  • 49
  • 232
  • 283