angular - Angular 9 Karma-Jasmine 测试不适用于 ViewChild
问题描述
我使用 Jasmine 在 Angular9 中为我的应用程序进行测试。我在执行应该可以工作的测试时遇到问题。我有一个文件“book-edit.component.html”,其中包含我要测试的页面的视图,特别是这部分:
<form *ngIf='activeForm == "templateDriven"' #templateForm='ngForm'>
<div class="row mt-3">
<div class="col-6">
Template-Driven Form
</div>
</div>
<!-- "touched" indicates modified -->
<div class="row">
<div class="col-12 form-group title-group">
<label for="title">Title</label>
<input [(ngModel)]='book.title' name='title2' type='text' id='title2' class='title form-control'
#title2='ngModel' minlength='3' required>
<!-- in order to prevent an error signal in case of title2 is invalid, is useful to check that client have touch that
filed. Initially title2 condition are not valid, but just because client doesn't touch that field. For this reason it
in enough to add AND clause in with we can check that that field is dirty(when a client text into that field) or toched
anyay () (AND invalid). Thus, if it is invalid it show the parent div. In a more specific way, it will visualize the child
div based on the type of error (required or minlenght) -->
<div *ngIf='!title2.valid && (title2.dirty || title2.touched)' class='invalid-feedback'
style='display: block;'>
<div *ngIf='title2?.errors?.required'>
Title is required.
</div>
<div *ngIf='title2?.errors?.minlength'>
Title must have at least 3 characters long.
</div>
</div>
</div>
我想测试这部分代码:如果 title2 包含少于 3 个字母,它会给我错误(它有效,我尝试过没有测试)。因此,我想使用这样的测试来信任它(book-edit.component.spec.ts”:
it('should have title error if less than 3 symbols provided',
fakeAsync(() => {
component.activeForm = 'templateDriven';
fixture.detectChanges();
// get our form on the page by using templateForm. To do this add @ViewChild(NgForm) in book-edit.component.ts
let form = component.templateForm.form;
// tick() to say to other engine to go ahead and apply the separtions
tick();
form.setValue({
title2: 'te',
image2: 'http://test.com',
description2: 'none',
price2: 100
});
form.controls.title2.markAsTouched();
debugger;
//expect(form.controls.title2.errors).toBeTruthy();
expect(nativeElement.querySelector('.title-group').textContent).
toContain('Title must have at least 3 characters long.');
})
);
具有以下组件(book-edit.component.ts):
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { FormBuilder, FormGroup, Validators, AbstractControl, FormControl, NgForm } from '@angular/forms';
import { BookModel } from "../../models/book/book.model";
@Component({
selector: 'book-edit',
templateUrl: './book-edit.component.html',
styleUrls: ['./book-edit.component.css']
})
export class BookEditComponent implements OnInit {
bookEditForm: FormGroup;
book: BookModel;
activeForm: string = 'reactive';
// ViewChild: Property decorator that configures a view query.
// The change detector looks for the first element or the directive matching the selector in the view DOM. If the view DOM changes, and a new child matches the selector, the property is updated.
@ViewChild(NgForm) templateForm: NgForm;
constructor(fb: FormBuilder, private route: ActivatedRoute) {
this.bookEditForm = fb.group({
//define a group and optionally defide if it is required
title: ['', Validators.required],
image: ['', Validators.required],
description: [''],
price: ['']
});
// subscribe to some changes
route.params.subscribe(res => {
if(this.book == null){
this.book = new BookModel('','','',0);
}
})
}
submitReactiveForm() {
let bookData = this.prepareSaveBook();
this.book = new BookModel(bookData.image,
bookData.title,
bookData.description,
bookData.price
);
this.book.save();
}
prepareSaveBook() {
const formModel = this.bookEditForm.value;
return formModel;
}
ngOnInit(): void {
}
}
当然,我放了“@ViewChild”是为了让测试检测表单上的变化。事实上,在测试中,我试图输入一个少于 3 个字母的名称,只是为了检查是否有错误和消息“标题必须至少有 3 个字符长”。出现。因此,最后我尝试expect(nativeElement.querySelector('.title-group').textContent).toContain('Title must have at least 3 characters long.');
检查我的主要 div(在 book-edit.component.html 中)是否还包含错误消息,因为 *ngIf 已满足,但不包含。它不起作用,并且控制台仅捕获“测试”值(通过该 div 清晰显示的文本)而不是“测试标题必须至少有 3 个字符长。”。我调试了代码并检查了表单是否正确初始化(title2:“te”,title2被触摸并且title2无效)但它似乎无法读取由*ngIf解锁的div的包含,
解决方案
推荐阅读
- sql - 在其他 .log 文件/Wildfly 11 中记录 org.hibernate.SQL
- excel-formula - 使用excel公式按平均值计算月份和年份
- python - 用python生成真正的随机数
- reactjs - 为什么 React 组件更新不起作用
- mysql - 使用 SQL 连接基于聚合函数的多个列
- python - 如何将 feed_dict 和 placeholder 迁移到 TensorFlow 2?
- javascript - 可访问性:这是没有带有点击处理程序的键盘侦听器的有效用例吗?
- c# - EF Core 错误 - SqlException:无效的对象名称“葡萄”
- python - 与 discord.embed 相关的错误
- node.js - mongoose 删除之前上传的文件