programing

Angular에서 라우터를 사용하는 구성 요소를 단위 테스트하려면 어떻게 해야 합니까?

instargram 2023. 9. 14. 21:38
반응형

Angular에서 라우터를 사용하는 구성 요소를 단위 테스트하려면 어떻게 해야 합니까?

Angular 2.0.0에서 Router를 사용하는 컴포넌트를 유닛 테스트하고 있습니다.그러나 '제공된 매개변수가 콜 대상의 서명과 일치하지 않습니다' 오류가 발생합니다.스펙의 Visual studio 코드에서 빨간색으로 강조 표시된 새 라우터()입니다.

정확한 구문은 무엇입니까?

내 코드는 다음과 같습니다.

스펙테츠

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) {}

Router Testing Module(라우터 테스트 모듈)을 사용할 수도 있고,spyOnnavigate이와 같은 기능을 합니다.

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); // TestBed.inject(Router) for Angular 9+

    });

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

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

그 이유는.Route구성자에게 전달될 것으로 예상되는 일부 의존성이 있습니다.

각도 성분을 사용하는 경우 분리 검정을 시도해서는 안 됩니다.테스트 환경을 준비하려면 Angular testing infrastructure를 사용해야 합니다.즉, 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테스트를 위해 모듈을 처음부터 구성합니다.당신은 그것을 거의 같은 방식으로 구성합니다.@NgModule.

여기서 우리는 라우터를 조롱하고 있을 뿐입니다.우리는 단지 유닛 테스트이기 때문에 실제 라우팅 설비를 원하지 않을 수 있습니다.우리는 단지 그것이 올바른 주장으로 불리는지 확인하고 싶을 뿐입니다.가짜와 스파이가 우리를 위해 그 요청을 포착할 수 있을 겁니다.

실제 라우터를 사용하려면 사용해야 합니다.RouterTestingModule, 경로를 설정할 수 있습니다.여기여기의 예시 보기

참고 항목:

구성 요소 컨트롤러에 Route service를 주입하는 경우의 예시는 다음과 같습니다.

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();
  }));
});

우리는 또한 다음과 같은 다른 기능성 물질을 테스트할 수 있습니다.navigate(). 만일의 경우:

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);
      });
}));

모든 모의 구성요소(mock.components.specs.ts)가 있는 내 파일

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

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

export class DummyHomeComponent { }

재스민은 완전한 스파이 물체와 함께 더 잘 어울립니다.

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

이를 달성하기 위한 또 다른 방법은 Location 객체를 통해 현재 URL을 확인하는 것입니다.

아래 예에서 우리는...

  1. 구성 요소 검색
  2. 테스트가 의도한 대로 비동기 작업을 실행하도록 fakeAsynctick을 사용합니다.
  3. 클릭 이벤트를 트리거합니다.
  4. 현재 url이 무엇인지 확인합니다.
it('navigates on NavToolComponent button click', fakeAsync(() => {
  // find component
  const button = fixture.debugElement.query(By.directive(NavToolComponent));
  expect(button).withContext('NavToolComponent button exists').toBeTruthy();

  // trigger click event
  button.nativeElement.click();

  // let async operations happen
  fixture.detectChanges();
  tick();

  // check current URL
  const location = TestBed.inject(Location);
  expect(location.path()).toEqual('/portfolio/trading');
}));

언급URL : https://stackoverflow.com/questions/39791773/how-can-i-unit-test-a-component-that-uses-the-router-in-angular

반응형