如何解决Angular 中的深度测试组件和使用 debugElement 访问 html 的问题
我的 angular 应用程序中有一个组件层次结构,如下所示:
BookmarkContainer
具有以下子组件:
BookmarksListComponent
CreateBookmarkComponent
BookmarksListComponent
的 ngFor
为 BookmarkItemComponent
我正在尝试使用 BookmarkItemComponent
及其 BookmarkContainer
方法从 DebugElement
的测试中访问 query()
的模板。
这是 BookmarkContainer
的代码:
@Component({
selector: 'app-bookmarks-container',templateUrl: './bookmarks.container.html',styleUrls: ['./bookmarks.container.scss']
})
export class BookmarksContainerComponent implements OnInit {
bookmarks$: Observable<Bookmark[]>;
newBookmark: Bookmark;
deletedBookmarkId: number;
constructor(private bookmarkService: BookmarkService) {}
ngOnInit(): void {
this.setBookmarks();
}
private setBookmarks() {
this.bookmarks$ = this.bookmarkService
.currentUser()
.pipe(
mergeMap(session => this.bookmarkService.search({ account: session.user.uid }))
);
}
}
这里是相应的测试:
describe('BookmarkContainerComponent',() => {
let component: BookmarksContainerComponent;
let fixture: ComponentFixture<BookmarksContainerComponent>;
let httpTestingController: HttpTestingController;
const aBookmark: Bookmark = {
id: 42,title: 'a bookmark',url: 'http://www.example.com',account: '1'
};
const anotherBookmark: Bookmark = {
id: 43,title: 'another bookmark',url: 'http://www.example.fr',account: '1'
};
beforeEach(async(() => {
Testbed.configureTestingModule({
imports: [HttpClientTestingModule,ReactiveFormsModule],declarations: [BookmarksContainerComponent,BookmarksListComponent,BookmarkItemComponent,CreateBookmarkComponent],}).compileComponents();
}));
beforeEach(() => {
fixture = Testbed.createComponent(BookmarksContainerComponent);
component = fixture.componentInstance;
httpTestingController = Testbed.inject(HttpTestingController);
fixture.detectChanges();
});
it('should create',() => {
expect(component).toBeTruthy();
});
it('should search bookmarks',fakeAsync(() => {
const sessionRequest = httpTestingController.expectOne('/api/system/connect');
sessionRequest.flush({ user: { uid: '1' } });
const bookmarksRequest = httpTestingController.expectOne('/api/bookmarks_link/search');
bookmarksRequest.flush([aBookmark,anotherBookmark]);
//Here I am not sure how to access the li(s) from the BookmarkItemComponent
const item = fixture.debugElement.query(By.directive(BookmarkItemComponent));
});
我尝试从 li(s)
访问 BookmarkItemComponent
但没有成功:item
始终是 null
。我怀疑这与 BookmarkItemComponent
的嵌套级别有关...有人可以帮忙吗?
编辑:
BookmarkContainer
的模板:
<app-bookmarks-list
[bookmarks]="bookmarks$ | async"
[newBookmark]="newBookmark"
[updatedBookmark]="updatedBookmark"
[deletedBookmark]="deletedBookmarkId"
(deleteBookmarkEvt)="confirmDeleteBookmark($event)"
(updateBookmarkEvt)="openUpdateForm($event)">
</app-bookmarks-list>
...
BookmarksListComponent
的模板:
<ng-container *ngFor="let bookmark of bookmarks">
<div class="bookmark">
<div class="">
<ul class="bookmark-list">
<app-bookmark-item
[bookmark]="bookmark"
(deleteBookmarkEvt)="deleteBookmark($event)"
(updateBookmarkEvt)="updateBookmark($event)"
>
</app-bookmark-item>
</ul>
</div>
</div>
</ng-container>
BookmarkItemComponent
的模板:
<li class="bookmark-item bookmark-item-{{ bookmark.id }}">
<span class="bookmark-icon"></span>
<span class="bookmark-text">
<a href="{{ bookmark.url }}" target="_blank" title="{{ 'BOOKMARKS.OPEN' | translate}}">
{{bookmark.title}}
</a>
</span>
<span class="bookmark-actions">
<a title="{{ 'GLOBAL.UPDATE' | translate}}" (click)="updateBookmark(bookmark)">
<i class="glyphicon glyphicon-pencil"></i>
</a>
<a title="{{ 'GLOBAL.DELETE' | translate}}" (click)="deleteBookmark(bookmark.id)">
<i class="glyphicon glyphicon-remove "></i>
</a>
</span>
</li>
解决方法
为了查看 DOM 中出现的 http 响应数据,您需要在 fixture.detectChanges()
之后执行一个 request.flush(...)
。另外,我会删除 fakeAsync
包装。应该不需要。
例如,
it('should search bookmarks',function() {
const sessionRequest = httpTestingController.expectOne('/api/system/connect');
sessionRequest.flush({ user: { uid: '1' } });
const bookmarksRequest = httpTestingController.expectOne('/api/bookmarks_link/search');
bookmarksRequest.flush([aBookmark,anotherBookmark]);
// add detectChanges here
fixture.detectChanges();
// item should be defined now.
const item = fixture.debugElement.query(By.directive(BookmarkItemComponent));
});
,
您可以尝试在 beforeEach 上添加 async
吗?
beforeEach(async() => {
fixture = TestBed.createComponent(BookmarksContainerComponent);
component = fixture.componentInstance;
httpTestingController = TestBed.inject(HttpTestingController);
fixture.detectChanges();
});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。