ActivatedRoute의 매개 변수에 따라 구성 요소를 유닛 테스트하는 방법은 무엇입니까?
개체를 편집하는 데 사용되는 구성 요소를 유닛 테스트하는 중입니다. 개체는 한 개가고니다를 가지고 .id
서비스에서 호스팅되는 개체 배열에서 특정 개체를 가져오는 데 사용됩니다. 정id
변수를 됩니다. 라팅을통전는변통조다특니됩히달해를수개매우,ActivatedRoute
학생들
생성자는 다음과 같습니다.
constructor(private _router:Router, private _curRoute:ActivatedRoute, private _session:Session) {}
ngOnInit() {
this._curRoute.params.subscribe(params => {
this.userId = params['id'];
this.userObj = this._session.allUsers.filter(user => user.id.toString() === this.userId.toString())[0];
저는 이 부품에 대한 기본 단위 테스트를 실행하고 싶습니다.하지만, 저는 어떻게 주사를 놓을 수 있는지 확신할 수 없습니다.id
매개 변수이며 구성 요소에는 이 매개 변수가 필요합니다.
그건 그렇고, 나는 이미 모의고사를 가지고 있습니다.Session
서비스, 그러니까 걱정하지 마세요.
이를 위한 가장 간단한 방법은 그냥 사용하는 것입니다.useValue
모의할 값의 관찰 가능한 값을 제공합니다.
RxJS < 6
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
...
{
provide: ActivatedRoute,
useValue: {
params: Observable.of({id: 123})
}
}
RxJS > = 6
import { of } from 'rxjs';
...
{
provide: ActivatedRoute,
useValue: {
params: of({id: 123})
}
}
8에는 에 8+는 .RouterTestingModule
있사수있다니습용할록도액에 할 수 .ActivatedRoute
또는Router
구성 요소의.또한 로의 경로를 전달할 수 있습니다.RouterTestingModule
그리고 요청된 경로의 방법을 위해 스파이를 만듭니다.
예를 들어 내 구성 요소에는 다음이 있습니다.
ngOnInit() {
if (this.route.snapshot.paramMap.get('id')) this.editMode()
this.titleService.setTitle(`${this.pageTitle} | ${TAB_SUFFIX}`)
}
그리고 제 시험은 다음과 같습니다.
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProductLinePageComponent ],
schemas: [NO_ERRORS_SCHEMA],
imports: [
RouterTestingModule.withRoutes([])
],
})
.compileComponents()
}))
beforeEach(() => {
router = TestBed.get(Router)
route = TestBed.get(ActivatedRoute)
})
나중에 'it' 섹션에서 확인할 수 있습니다.
it('should update', () => {
const spyRoute = spyOn(route.snapshot.paramMap, 'get')
spyRoute.and.returnValue('21')
fixture = TestBed.createComponent(ProductLinePageComponent)
component = fixture.componentInstance
fixture.detectChanges()
expect(component).toBeTruthy()
expect(component.pageTitle).toBe('Edit Product Line')
expect(component.formTitle).toBe('Edit Product Line')
// here you can test the functionality which is triggered by the snapshot
})
비슷한 방법으로, 저는 당신이 직접 테스트할 수 있다고 생각합니다.paramMap
유로를 spyOnProperty
관찰 가능한 것을 반환하거나 rxjs 대리석을 사용하여 재스민 방법.시간을 절약할 수 있고 추가 모의 수업을 유지할 필요가 없습니다.그것이 유용하고 이치에 맞기를 바랍니다.
어떻게 해야 할지 알아냈어요!
때부터ActivatedRoute
는 서비스이며, 이를 위한 모의 서비스를 구축할 수 있습니다.이것을 모의 서비스라고 부르자.MockActivatedRoute
는 연겠습다니를 할 것입니다.ActivatedRoute
MockActivatedRoute
같이 표시됩니다.
class MockActivatedRoute extends ActivatedRoute {
constructor() {
super(null, null, null, null, null);
this.params = Observable.of({id: "5"});
}
인super(null, ....)
4개의 필수 매개 변수가 있는 슈퍼 클래스를 초기화합니다. 중 하지 않기 하여 그나러, 경우이우, 이매한수중개, 우그초다니합기화, 리는을들것에때문않으로 설정합니다.null
가치.우리가 필요로 하는 것은 가치입니다.params
은 것은그입니다.Observable<>
러므로와 함께, 함께와와 함께.this.params
는 우는가치무니다합시의 합니다.params
그리고 그것이 되도록 초기화합니다.Observable<>
테스트 대상이 의존하는 매개 변수의.
그런 다음 다른 모의 서비스와 마찬가지로 초기화하고 구성 요소의 공급자를 재정의합니다.
행운을 빕니다.
제가 최근에 각도 2.0으로 테스트한 방법은 다음과 같습니다.
import { ActivatedRoute, Data } from '@angular/router';
및 공급자 섹션에서
{
provide: ActivatedRoute,
useValue: {
data: {
subscribe: (fn: (value: Data) => void) => fn({
yourData: 'yolo'
})
}
}
}
활성화된 경로에 대한 모의실험을 추가하기만 하면 됩니다.
providers: [
{ provide: ActivatedRoute, useClass: MockActivatedRoute }
]
...
class MockActivatedRoute {
// here you can add your mock objects, like snapshot or parent or whatever
// example:
parent = {
snapshot: {data: {title: 'myTitle ' } },
routeConfig: { children: { filter: () => {} } }
};
}
라우팅 경로에 대한 테스트 제품군을 만드는 동안 다음과 같은 문제가 발생했습니다.
{
path: 'edit/:property/:someId',
component: YourComponent,
resolve: {
yourResolvedValue: YourResolver
}
}
구성 요소에서 전달된 속성을 다음과 같이 초기화했습니다.
ngOnInit(): void {
this.property = this.activatedRoute.snapshot.params.property;
...
}
테스트를 실행할 때 모의 ActiveRoute "useValue"에서 속성 값을 전달하지 않으면 "fix"를 사용하여 변경 사항을 감지할 때 정의되지 않습니다.변경사항()"을 검색합니다.이는 ActivatedRoute의 모의 값에 params.property 속성이 포함되어 있지 않기 때문입니다.그런 다음 fixture가 구성 요소에서 'this.property'를 초기화하려면 mock useValue에 이러한 매개변수가 있어야 합니다.다음과 같이 추가할 수 있습니다.
let fixture: ComponentFixture<YourComponent>;
let component: YourComponent;
let activatedRoute: ActivatedRoute;
beforeEach(done => {
TestBed.configureTestingModule({
declarations: [YourComponent],
imports: [ YourImportedModules ],
providers: [
YourRequiredServices,
{
provide: ActivatedRoute,
useValue: {
snapshot: {
params: {
property: 'yourProperty',
someId: someId
},
data: {
yourResolvedValue: { data: mockResolvedData() }
}
}
}
}
]
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(YourComponent);
component = fixture.debugElement.componentInstance;
activatedRoute = TestBed.get(ActivatedRoute);
fixture.detectChanges();
done();
});
});
다음과 같이 테스트를 시작할 수 있습니다.
it('should ensure property param is yourProperty', async () => {
expect(activatedRoute.snapshot.params.property).toEqual('yourProperty');
....
});
이제 다른 속성 값을 테스트하고 싶다고 가정하면 다음과 같이 모의 활성화된 경로를 업데이트할 수 있습니다.
it('should ensure property param is newProperty', async () => {
activatedRoute.snapshot.params.property = 'newProperty';
fixture = TestBed.createComponent(YourComponent);
component = fixture.debugElement.componentInstance;
activatedRoute = TestBed.get(ActivatedRoute);
fixture.detectChanges();
expect(activatedRoute.snapshot.params.property).toEqual('newProperty');
});
이것이 도움이 되길 바랍니다!
각도 11: 사양 파일에 추가합니다.
imports: [
RouterTestingModule.withRoutes([])
],
이것은 단 한 줄로 도움이 됩니다. 다른 줄로 제공자를 조롱해야 합니다.
다음을 사용하여 이 작업을 수행할 수 있습니다.beforeAll
기능.부터beforeAll
당신의 모든 사람들 앞에 불려집니다.beforeEach
함수를 사용하면 구성 요소가 컴파일되기 전에 구성원 변수를 변경할 수 있습니다.
describe('MyComponent', () => {
let fakeActivatedRoute = {
paramMap: of(convertToParamMap({ id: '123' })),
queryParamMap: of(convertToParamMap({ query: 'active' }))};
beforeEach(async() => {
await TestBed.configureTestingModule({
providers: [
...
{ provide: ActivatedRoute, useValue: fakeActivatedRoute }],
}).compileComponents();
});
});
describe('id is present in route', () => {
beforeAll(() => {
fakeActivatedRoute.paramMap =
of(convertToParamMap({ id: '123' }));
fakeActivatedRoute.queryParamMap =
of(convertToParamMap({ query: '' }));
});
it('should call service to look up id', () => {
...
});
});
describe('id is not present in route', () => {
beforeAll(() => {
fakeActivatedRoute.paramMap =
of(convertToParamMap({ id: '' }));
fakeActivatedRoute.queryParamMap =
of(convertToParamMap({ query: '' }));
});
it('should not call service to look up id', () => {
...
});
});
describe('query is present in route', () => {
beforeAll(() => {
fakeActivatedRoute.paramMap =
of(convertToParamMap({ id: '123' }));
fakeActivatedRoute.queryParamMap =
of(convertToParamMap({ query: 'inactive' }));
});
it('should call service to look up the inactive id', () => {
...
});
});
});
Angular > 5에서 작업하는 일부 사용자의 경우, Observable.of();가 작동하지 않는 경우 'rxjs'에서 {of} 가져오기를 통해 ()만 사용할 수 있습니다.
테스트 클래스에 다음과 같이 공급자 추가:
{
provide: ActivatedRoute,
useValue: {
paramMap: of({ get: v => { return { id: 123 }; } })
}
}
지금까지의 다른 모든 답변은 경로 매개 변수에 대한 값만 제공합니다.경로 변경 트리거 자체를 테스트하려면 어떻게 해야 합니까?source.next()를 사용하여 경로 변경을 트리거할 수 있도록 테스트의 활성화된 경로에 Subject 및 해당 Observable을 제공할 수 있습니다.
테스트 중인 코드:
constructor(private readonly route: ActivatedRoute) {}
ngOnInit(): void {
this.routeParamSubscription = this.route.params.subscribe((params) => {
if (params['id']) {
this.loadDetails(params['id']);
}
});
}
테스트 코드:
let routeChangeSource: BehaviorSubject<Params>;
// In TestBed.configureTestingMethod
...
providers: [
{
provide: ActivatedRoute,
useValue: {
params: routeChangeSource.asObservable()
}
}
]
...
it('loads data on route change', fakeAsync(() => {
const spy = spyOn(component, 'loadDetails').and.callThrough();
routeChangeSource.next({ id: 99 });
tick();
expect(spy).toHaveBeenCalledOnceWith(99);
}));
이렇게 하면 경로 변경 후 트리거된 작업을 테스트하고 해당 작업이 활성화되었는지 확인합니다.
이 경우 매개 변수에 액세스하는 경우get
의 방법paramMap
.ts에서:
this.id= this.activatedRoute.snapshot.paramMap.get('id');
.spec.ts에서
providers: [
{
provide: ActivatedRoute,
useValue: {
snapshot: {
paramMap: {
get() {
return '97dbf5d7';
}
}
}
}
}
]
언급URL : https://stackoverflow.com/questions/38356084/how-to-unit-test-a-component-that-depends-on-parameters-from-activatedroute
'programing' 카테고리의 다른 글
간단한 Postgre에서 변수를 사용하는 방법SQL 스크립트? (0) | 2023.05.01 |
---|---|
mongodb에서 "deletemany"와 "remove"의 차이점은 무엇입니까? (0) | 2023.05.01 |
디렉토리의 대문자를 변경했는데 Git이 디렉토리를 인식하지 못하는 것 같습니다. (0) | 2023.05.01 |
플랫폼이 동일한 경우에도 "잘못된 형식의 프로그램을 로드하려고 했습니다." (0) | 2023.05.01 |
IE 숫자에서 항목을 반복하지 않고 카운트하시겠습니까? (0) | 2023.05.01 |