programing

Angular 2/4/6/7-라우터를 사용한 단위 테스트

randomtip 2021. 1. 18. 07:55
반응형

Angular 2/4/6/7-라우터를 사용한 단위 테스트


Angular 2.0.0에서는 Router를 사용하는 구성 요소를 단위 테스트하고 있습니다. 그러나 '제공된 매개 변수가 호출 대상의 서명과 일치하지 않습니다.'라는 메시지가 나타납니다. 오류. spec.ts의 Visual Studio 코드에서 빨간색으로 강조 표시된 새 Router ()입니다.

누군가가 올바른 구문이 무엇인지 알려줄 수 있다면 정말 감사합니다. 미리 감사드립니다. 내 코드는 다음과 같습니다.

사양

import { TestBed, async } from '@angular/core/testing';
import { NavToolComponent } from './nav-tool.component';
import { ComponentComm } from '../../shared/component-comm.service';
import { Router } from '@angular/router';

describe('Component: NavTool', () => {
  it('should create an instance', () => {
    let component = new NavToolComponent( new ComponentComm(), new Router());
    expect(component).toBeTruthy();
  });
});

구성 요소 생성자

constructor(private componentComm: ComponentComm, private router: Router) {}

RouterTestingModule을 사용하고 다음과 같이 탐색 기능을 감시 할 수도 있습니다.

import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';

import { MyModule } from './my-module';
import { MyComponent } from './my-component';

describe('something', () => {

    let fixture: ComponentFixture<LandingComponent>;
    let router: Router;

    beforeEach(() => {

        TestBed.configureTestingModule({
            imports: [
                MyModule,
                RouterTestingModule.withRoutes([]),
            ],
        }).compileComponents();

        fixture = TestBed.createComponent(MyComponent);
        router = TestBed.get(Router);

    });

    it('should navigate', () => {
        const component = fixture.componentInstance;
        const navigateSpy = spyOn(router, 'navigate');

        component.goSomewhere();
        expect(navigateSpy).toHaveBeenCalledWith(['/expectedUrl']);
    });
});

Route생성자에 전달 될 것으로 예상되는 종속성이 있기 때문 입니다.

Angular 구성 요소를 사용하는 경우 격리 된 테스트를 수행해서는 안됩니다. Angular 테스트 인프라를 사용하여 테스트 환경을 준비해야합니다. 즉, Angular가 구성 요소 를 생성하고 모든 것을 생성하는 대신 필요한 모든 종속성을 주입 할 수 있도록합니다 .

시작하려면 다음과 같은 것이 있어야합니다.

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

describe('Component: NavTool', () => {
  let mockRouter = {
    navigate: jasmine.createSpy('navigate')
  };
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ NavToolComponent ],
      providers: [
        { provide: Router, useValue: mockRouter },
        ComponentComm
      ]
    });
  });
  it('should click link', () => {
    let fixture = TestBed.createComponent(NavToolComponent);
    fixture.detectChanges();
    let component: NavToolComponent = fixture.componentInstance;
    component.clickLink('home');
    expect(mockRouter.navigate).toHaveBeenCalledWith(['/home']);
  });
});

아니면 그런 것. 을 사용하여 TestBed테스트를 위해 처음부터 모듈을 구성합니다. .NET과 거의 동일한 방식으로 구성합니다 @NgModule.

여기서 우리는 라우터를 조롱하고 있습니다. 우리는 단지 단위 테스트이기 때문에 실제 라우팅 기능을 원하지 않을 수도 있습니다. 우리는 올바른 인수로 호출되었는지 확인하고 싶습니다. 모의와 스파이 는 우리를 요구하는 것을 포착 할 수있을 것입니다.

If you do want to use the real router, then you need to use the RouterTestingModule, where you can configure routes. See an example here and here

See Also:


Jasmine goes one better with full spy objects...

describe(..., () => {
    const router = jasmine.createSpyObj('Router', ['navigate’]);
    ...
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            providers: [  { provide: Router, useValue: router } ],
            ...
    });        
});

Here an axample if we inject Route service in our component controller:

import { TestBed, async } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; // Because we inject service in our component
import { Router } from '@angular/router'; // Just if we need to test Route Service functionality

import { AppComponent } from './app.component';
import { DummyLoginLayoutComponent } from '../../../testing/mock.components.spec'; // Because we inject service in your component

describe('AppComponent', () => {
  let router: Router; // Just if we need to test Route Service functionality

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        DummyLoginLayoutComponent // Because we inject service in our component
      ],
      imports: [
        RouterTestingModule.withRoutes([
          { path: 'login', component: DummyLoginLayoutComponent },
        ]) // Because we inject service in our component
      ],
    }).compileComponents();

    router = TestBed.get(Router); // Just if we need to test Route Service functionality
    router.initialNavigation(); // Just if we need to test Route Service functionality
  }));

  it('should create the app', async(() => {
    const fixture = TestBed.createComponent(AppComponent);
    const app = fixture.debugElement.componentInstance;
    expect(app).toBeTruthy();
  }));
});

We can also test other functionalitites such as navigate(). Just in case:

it('should call eventPage once with /register path if event is instanceof NavigationStart', fakeAsync(() => {
    spyOn(analyticService, 'eventPage');
    router.navigate(['register'])
      .then(() => {
        const baseUrl = window.location.origin;
        const url = `${baseUrl}/register`;
        expect(analyticService.eventPage).toHaveBeenCalledTimes(1);
        expect(analyticService.eventPage).toHaveBeenCalledWith(url);
      });
}));

My file with all mock components (mock.components.specs.ts)

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

@Component({
    selector: 'home',
    template: '<div>Dummy home component</div>',
    styleUrls: []
})

export class DummyHomeComponent { }

ReferenceURL : https://stackoverflow.com/questions/39791773/angular-2-4-6-7-unit-testing-with-router

반응형