web-dev-qa-db-ja.com

Angular 2Jasmineコンポーネントの機能をテストする方法

Angular 2で関数のクリックイベントをモックするにはどうすればよいですか?ホームコンポーネントの場合:

ホームコンポーネント

import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  moduleId: module.id,
  templateUrl: 'home.component.html',
  styleUrls: ['home.component.css'],
  selector: 'home',
})
export class HomeComponent {

    constructor(private router: Router) {

    }

    redirectToUpload() {
        this.router.navigate(['/upload']);
    }
    redirectToAbout() {
        this.router.navigate(['/about']);
    }

}

ホームコンポーネント仕様

import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { HomeComponent } from './home.component';
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { HomeModule } from './home.module';
import { RouterLinkStubDirective, RouterOutletStubComponent } from '../../../test/router-stubs';
import { RouterModule } from '@angular/router';


export function main() {

    let de: DebugElement;
    let comp: HomeComponent;
    let fixture: ComponentFixture<HomeComponent>;
    let mockRouter:any;
    class MockRouter {
        //noinspection TypeScriptUnresolvedFunction
        navigate = jasmine.createSpy('navigate');
    }



    describe('Home component', () => {

        // preparing module for testing
        beforeEach(async(() => {
            mockRouter = new MockRouter();
            TestBed.configureTestingModule({
                imports: [HomeModule],

            }).overrideModule(HomeModule, {
                remove: {
                    imports: [ RouterModule ],

                },
                add: {
                    declarations: [ RouterLinkStubDirective, RouterOutletStubComponent ],
                    providers: [ { provide: Router, useValue: mockRouter }],
                }
            }).compileComponents().then(() => {

                fixture = TestBed.createComponent(HomeComponent);
                comp = fixture.componentInstance;


            });
        }));
            tests();
        });

        function tests() {


            beforeEach(() => {
                // trigger initial data binding
                fixture.detectChanges();



                de = fixture.debugElement.query(By.css('h1'));

            });

            it('can instantiate Home', () => {
                expect(comp).not.toBeNull();
            });


            it('should have expected <h1> text', () => {
                fixture.detectChanges();
                const h1 = de.nativeElement;
                expect(h1.innerText).toMatch("Home");
            });          


        }

}

RedirectToUpload()とredirectToAbout()をテストしたいと思います。クリックをモックして、リダイレクトが指定されたリンクに対するものであることを確認するにはどうすればよいですか?

6
Bhetzie

まず、TypeScriptでテストを作成することをお勧めします。これにより、コンポーネントとテストの間の一貫性が保たれます。

スペックファイルの基本的な手順は次のとおりです。

要素を取得します(可能であればIdタグを使用することをお勧めします)

const element = fixture.debugElement.query(By.css("#your-element"));

イベントをトリガーします。 注:要素には(click)イベントが必要です

element.triggerEventHandler("click", null);

次に、イベントからの変更を検出します

fixture.detectChanges();

HTMLテンプレートでは、テストする関数を指すクリックイベントが必要になります(click)="redirectToUpload()"

7
ed-tester

ボタンを取得してクリックする必要があります

de.nativeElement.querySelector('.theButtonClass').click();

次に、スタブのnavigateメソッドが正しい引数で呼び出されていることを確認します

expect(mockRouter.navigate).toHaveBeenCalledWith(['/about']);

asyncを使用する必要がある場合とない場合があります。それが機能しない場合は、asyncを使用して、非同期クリックイベントが安定するのを待つ必要があるかもしれません

import { async } from '@angular/core/async';

it('..', async(() => {
  ...click();
  fixture.whenStable().then(() => {
    expect(mockRouter.navigate).toHaveBeenCalledWith(['/about']);
  })
})
6
Paul Samsotha