Angular????????????Component??Directive??Pipe ???Service
?????cipchk ???????[ 2017/6/15 10:55:18 ] ??????????????? ??????? Angular
?????????????Angular????????????????????????磺Component??Directive??Pipe ???Service?????????????????????????????????????????????????????????????????????????Щ?????????????????????磺Router??
???????????????????????????е? ????? ?????????????????Angular???????????Щ????????
?????????????????????????????1???
??????С????????????????????????
??????С??????????????????????
??????????????????????? TestComponent ??
???????beforeEach
?????? beforeEach ??????????????Angular??????????棬???????÷?????????????е???ж??????????????
????beforeEach ?????????????????????Щ??????????????
?????????????д???Angular????????????????????????????飬??????? TestBed.configureTestingModule ????????Angular?????????????????????????? NgModule???????????????????? NgModule ?????κβ???
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule]??
declarations: [TestComponent]
});
});
????????????κζ??????в????????????????????磺Http?????????? imports: [HttpModule] ??????ж??? NgModule д???????á?
????????????????????????????????????????????????????????????????ЩHTML????????????磺???????????????????????????????????????????????????????????????????????????????в????
?????????????????? Pipe ???????κ?HTML????????????????????????????????????
????1???????
??????ν????壬??????????????????????????????κ? HTML ?????????????????????????????????????????????????????????????????????DI???????????????????????????????????????????????????Service????????
let directive: LogDirective;
beforeEach(() => TestBed.configureTestingModule({
providers: [ LogDirective ]
}));
beforeEach(inject([ LogDirective ]?? c => {
directive = c;
}));
???????????????????????????????? inject ??????? LogDirective ???????????????????????????????
????2???????
????????????????????????????????????????????????????????????????????????????
@Component({
template: `<trade-view [id]="id" (close)="_close()"></trade-view>`
})
class TestComponent {
id: number = 0;
_close() { }
}
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule]??
declarations: [TestComponent]
});
fixture = TestBed.createComponent(TestComponent);
context = fixture.componentInstance;
el = fixture.nativeElement;
dl = fixture.debugElement;
});
????????? TestComponent ?????????????? ?????????? export ????????????????????????????????????á?
??????????????????? close ?????в?????????????????????????????????????????С?
??????Σ???? TestBed.createComponent(TestComponent) ??????????????????????洢??????
????fixture ?????????????????????DOM????????????????????????д?????????????????????????????????????????????? it ???????????á?
????nativeElement??debugElement??????
??????????DOM????????????Angular???а?????????磺
???? query ??????????????
???? triggerEventHandler ????DOM?????
????????Щ????????д?????????????????????и?????????????С????????????????
????????Component
????1?????
?????????б? ngOnInit ????????????????????????????
// trade-list.component.ts
@Component({
selector: 'trade-list'??
templateUrl: './trade-list.component.html'??
styleUrls: [ './trade-list.component.scss' ]
})
export class TradeListComponent {
constructor(private srv: TradeService) {}
ngOnInit() {
this.query();
}
ls: any[] = [];
query() {
this.srv.query().subscribe(res => {
this.ls = res;
});
}
}
?????????????? id ???????????????????????????????????? close ???????????????????
// trade-view.component.ts
@Component({
selector: 'trade-view'??
template: `
<h1>trade {{id}}</h1>
<dl *ngIf="item">
<dt>sku_id</dt><dd>{{item.sku_id}}</dd>
<dt>title</dt><dd>{{item.title}}</dd>
</dl>
<button (click)="_close()">Close</button>
`??
host: {
'[class.trade-view]': 'true'
}??
styles: [ `.trade-view { display: block; }` ]??
encapsulation: ViewEncapsulation.None
})
export class TradeViewComponent {
@Input() id: number;
@Output() close = new EventEmitter();
constructor(private srv: TradeService) {}
ngOnInit() {
this.get();
}
item: any;
get() {
this.srv.get(this.id).then(res => {
this.item = res;
});
}
_close() {
this.close.emit();
}
}
?????????????????????????????????????????????????@Input??@Output????????HTTP??????????????
???????????????????????????????????????????衣
????2????????? @NgModule
??????????? beforeEach ????????? ????? ??????????????飬???????????????
@Component({
template: `<trade-view [id]="id" (close)="_close()"></trade-view>`
})
class TestComponent {
@ViewChild(TradeViewComponent) comp: TradeViewComponent;
id: number = 0;
_close() { }
}
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule]??
declarations: [TradeViewComponent?? TestComponent]??
providers: [TradeService?? UserService]
});
fixture = TestBed.createComponent(TestComponent);
context = fixture.componentInstance;
el = fixture.nativeElement;
de = fixture.debugElement;
});
???????? TradeViewComponent ??????????? TradeService ?????????? UserService ??????????????????????????? HttpModule ??顣
??????????????????????????????????????????????????????????????С???????????????????????????????????????????????????????Ч??????????????
?????????????????? spyOn ??jasmine????????????????? TradeService ?? get ????????????Щ?????????????
let spy: jasmine.Spy;
const testTrade = { id: 10000 };
beforeEach(() => {
// ...
spy = spyOn(tradeService?? 'get').and.returnValue(Promise.resolve(testTrade));
// ...
});
????????????????????????е?????????? spyOn ?????????
??????beforeEach
????trade-list ????? trade-view ???????????????????HTML?????????????????????URL?????????????Щ????????????????????????????????????? @NgModule ????????????????????????????? NgModule ??
beforeEach(async(() => {
TestBed.configureTestingModule({
// ???
}).compileComponents();
// ???
????}));
???????? async() ??????????? compileComponents() ???????????κ????????????????????????????????????????????????????????????????????к????????ɡ??????? compileComponents() ?????????????????? templateUrl ?? styleUrls ?????????????????
????3??????????
???????????????????????????????????????????????????????????????????????????????????
????A??????????
???????? TradeViewComponent ???? ngOnInit ??????????????л?????????У????????????????
it('should be component initialized'?? () => {
context.id = 1;
fixture.detectChanges();
expect(el.querySelector('h1').innerText).toBe('trade 1');
????});
????context.id = 1; ?е? context ?????????????????????????????? id ????? 1 ??????Angular???????????????仯????????????????? fixture.detectChanges(); ????????Angular?仯???????????????????DOM????????????????? h1 DOM??????????? trade 1 ???????
????????仯???
?????????????????????????? ComponentFixtureAutoDetect ??????仯?? Angular ??????????
????TestBed.configureTestingModule({
???? { provide: ComponentFixtureAutoDetect?? useValue: true }
????});
?????????????????????Щ???????????????????????????????????????????
????B??spy ????
??????????????????????????????????????DOM?????????????? spyOn ??????????????????????????????? spy ????????????????????DOM?????????????????????????
it('should be component initialized (done)'?? (done: DoneFn) => {
context.id = 1;
fixture.detectChanges();
expect(spy.calls.any()).toBe(true?? 'get called');
spy.calls.mostRecent().returnValue.then(res => {
fixture.detectChanges();
expect(context.comp.item.id).toBe(testTrade.id);
expect(el.querySelector('dl')).not.toBeNull();
expect(el.querySelector('.sku-id').textContent).toBe('' + testTrade.sku_id);
expect(el.querySelector('.ware-title').textContent).toBe(testTrade.title);
done();
});
});
????????? spy.calls.any() ????е????κμ???????????????? true ??????????????????? ngOnInit ???????????Ρ?
??????Σ? spy.calls.mostRecent().returnValue ????? TradeServie ?? get() ?????????????????????????????????????????????????????????????????
????C????????
????????????У????????jasmine???????????????? get() ???????????????????????????????? then() ????????????????????????ɡ?
???????????????????д????
????async
it('should be component initialized (async)'?? async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(context.comp.item.id).toBe(testTrade.id);
expect(el.querySelector('dl')).not.toBeNull();
expect(el.querySelector('.sku-id').textContent).toBe('' + testTrade.sku_id);
expect(el.querySelector('.ware-title').textContent).toBe(testTrade.title);
});
}));
?? spy.calls.mostRecent().returnValue ?滻?? fixture.whenStable() ?????????Promise????Angular??????????????????Promise.resolve??
fakeAsync
it('should be component initialized (fakeAsync)'?? fakeAsync(() => {
fixture.detectChanges();
tick();
fixture.detectChanges();
expect(context.comp.item.id).toBe(testTrade.id);
expect(el.querySelector('dl')).not.toBeNull();
expect(el.querySelector('.sku-id').textContent).toBe('' + testTrade.sku_id);
expect(el.querySelector('.ware-title').textContent).toBe(testTrade.title);
}));
???? async ?????????????????????????????????
????fakeAsync??async????
????????????????????????????????? fixture.whenStable() ???? tick() ?????
????D?? @Input() ???????
??????????????????????????? context.id = 1; ?????????? trade-view ????????????????? 1 ???????????DOM??? trade 1 ??
????E?? @Output() ????????
????trade-view ?????????? (close) ?????????????????????????????????????????????????????????????????????????????????????????????
???????????? spyOn ????? ??????? ???????????????
??????????????????????? _close() ??
beforeEach(() => {
// ...
spyOn(context?? '_close');
// ...
});
??
it('should be call `close`'?? () => {
el.querySelector('button').click();
fixture.detectChanges();
expect(context._close).toHaveBeenCalled();
});
??????? close ??????????? Close ?????????????????????????e?????????? click ????????? toHaveBeenCalled ????????????е? _close() ??????????????????????? close ?????????????????????????????
??????
???·???
??????????????????
2023/3/23 14:23:39???д?ò??????????
2023/3/22 16:17:39????????????????????Щ??
2022/6/14 16:14:27??????????????????????????
2021/10/18 15:37:44???????????????
2021/9/17 15:19:29???·???????·
2021/9/14 15:42:25?????????????
2021/5/28 17:25:47??????APP??????????
2021/5/8 17:01:11