programing

Angular2(TypeScript)의 유닛 테스트/모킹 창 속성

padding 2023. 6. 12. 21:13
반응형

Angular2(TypeScript)의 유닛 테스트/모킹 창 속성

Angular2의 서비스를 위한 유닛 테스트를 만들고 있습니다.

서비스 내에 다음 코드가 있습니다.

var hash: string; hash = this.window.location.hash;

하지만 이 코드가 포함된 테스트를 실행하면 실패합니다.

Window의 모든 기능을 활용하면 좋겠지만 PhantomJs를 사용하고 있기 때문에 불가능할 것 같습니다(같은 결과를 내는 Chrome도 사용해 보았습니다).

AngularJs에서, 저는 $Window(또는 적어도 문제의 속성)를 조롱하는 데 의지했을 것입니다. 하지만 Angular2 유닛 테스트에 대한 문서가 많지 않기 때문에 이것을 어떻게 하는지 잘 모르겠습니다.

누가 도와줄 수 있습니까?

Angular 2에서 다음을 사용할 수 있습니다.@Inject()다음과 같이 문자열 토큰을 사용하여 이름을 지정하여 창 개체를 주입하는 기능

  constructor( @Inject('Window') private window: Window) { }

에서@NgModule그런 다음 동일한 문자열을 사용하여 제공해야 합니다.

@NgModule({
    declarations: [ ... ],
    imports: [ ... ],
    providers: [ { provide: 'Window', useValue: window } ],
})
export class AppModule {
}

그런 다음 토큰 문자열을 사용하여 조롱할 수도 있습니다.

beforeEach(() => {
  let windowMock: Window = <any>{ };
  TestBed.configureTestingModule({
    providers: [
      ApiUriService,
      { provide: 'Window', useFactory: (() => { return windowMock; }) }
    ]
  });

이것은 Angular 2.1.1에서 작동했으며, 2016-10-28년 현재 최신 버전입니다.

Angular 4.0.0 AOT에서는 작동하지 않습니다.https://github.com/angular/angular/issues/15640

@estus가 코멘트에서 언급했듯이 라우터에서 해시를 가져오는 것이 좋습니다.하지만 여러분의 질문에 직접 대답하기 위해서는, 여러분이 사용하는 장소에 창문을 주입해야 합니다. 그래서 여러분은 시험하는 동안 창문을 조롱할 수 있습니다.

먼저, angular2 공급자에 창을 등록합니다. 만약 당신이 이것을 여기저기서 사용한다면 아마도 글로벌한 곳일 것입니다.

import { provide } from '@angular/core';
provide(Window, { useValue: window });

이것은 의존성 주입이 유형을 요청할 때 각도를 나타냅니다.Window그것은 글로벌을 반환해야 합니다.window.

이제 사용 중인 위치에서 글로벌을 직접 사용하는 대신 클래스에 이 정보를 주입합니다.

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

@Component({ ... })
export default class MyCoolComponent {
    constructor (
        window: Window
    ) {}

    public myCoolFunction () {
        let hash: string;
        hash = this.window.location.hash;
    }
}

이제 여러분은 시험에서 그 가치를 조롱할 준비가 되었습니다.

import {
    beforeEach,
    beforeEachProviders,
    describe,
    expect,
    it,
    inject,
    injectAsync
} from 'angular2/testing';

let myMockWindow: Window;
beforeEachProviders(() => [
    //Probably mock your thing a bit better than this..
    myMockWindow = <any> { location: <any> { hash: 'WAOW-MOCK-HASH' }};
    provide(Window, {useValue: myMockWindow})
]);

it('should do the things', () => {
    let mockHash = myMockWindow.location.hash;
    //...
});

RC4 방법 이후provide()RC4 이후에 이를 처리하는 방법은 다음과 같습니다.

  let myMockWindow: Window;

  beforeEach(() => {
    myMockWindow = <any> { location: <any> {hash: 'WAOW-MOCK-HASH'}};
    addProviders([SomeService, {provide: Window, useValue: myMockWindow}]);
  });

어떻게 작동하는지 알아내는 데 시간이 좀 걸립니다.

공장이 내장된 사출 토큰은 가야 할 길처럼 보입니다.

창, 문서, localStorage, 콘솔 등 글로벌 브라우저에 사용합니다.

핵심/핵심/핵심/핵심/핵심

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

export const WINDOW = new InjectionToken<Window>(
    'Window',
    {
        providedIn: 'root',
        factory(): Window {
            return window;
        }
    }
);

주입:

constructor(@Inject(WINDOW) private window: Window)

단위 테스트:

const mockWindow = {
  setTimeout: jest.fn(),
  clearTImeout: jest.fn()
};

TestBed.configureTestingModule({
  providers: [
    {
      provide: WINDOW,
      useValue: mockWindow
    }
  ]
});

여기 보시는 것처럼 Angular-Team이 서비스를 테스트하기 위해 권장하는 방법인 가장 쉬운 솔루션을 왜 아무도 제공하지 않았는지 정말 이해할 수 없습니다.대부분의 경우 테스트베드 문제를 전혀 처리할 필요가 없습니다.

또한 구성요소 및 지침에 대해서도 이 접근 방식을 사용할 수 있습니다.이 경우 구성 요소 인스턴스가 아니라 클래스 인스턴스를 만듭니다.즉, 구성요소 템플릿 내에서 사용되는 하위 구성요소도 처리할 필요가 없습니다.

생성자에 Window를 주입할 수 있다고 가정합니다.

constructor(@Inject(WINDOW_TOKEN) private _window: Window) {}

.spec 파일에서 다음을 수행합니다.

describe('YourService', () => {
  let service: YourService;
  
  beforeEach(() => {
    service = new YourService(
      {
        location: {hash: 'YourHash'} as any,
        ...
      } as any,
      ...
    );
  });
}

다른 속성은 신경쓰지 않기 때문에 일반적으로 유형 캐스트를 추가합니다.any다른 모든 속성도 포함하여 입력하십시오.

이 조롱당한 하다면, 여러분은 하고, 조당한속다값필경이요단우한는다순해있에니수습히값변할당을 사용하여 값을 수.returnValue자스민의 경우:

const spy: any = spyOn((service as any)._window, 'location').and.returnValue({hash: 'AnotherHash'});

또는

const spy: any = spyOn((service as any)._window.location, 'hash').and.returnValue('AnotherHash');

언급URL : https://stackoverflow.com/questions/36568913/unit-testing-mocking-window-properties-in-angular2-typescript

반응형