angular - expect(component).toBeTruthy() 失败
问题描述
我想为组件编写单元测试。第一次测试失败,出现以下错误:
错误:预期未定义是真实的。
it
块输出错误:
it('should create', () => {
expect(component).toBeTruthy();
});
登录模板:
<h3>Login</h3>
<form class="form form-group" (ngSubmit)="onSubmit()">
<div class="row">
<label for="email" class="login-form-label col-4">Email:</label>
<input ngModel [(ngModel)]="email" name="email" (ngModelChange)="validateEmail()" type="email" id="email" class="col-3 form-control">
<span class="error col-sm-4">{{ this.emailErr }}</span>
</div>
<br>
<div class="row">
<label for="password" class="login-form-label col-4">Wachtwoord:</label>
<input ngModel [(ngModel)]="password" name="password" (ngModelChange)="validatePassword()" type="password" id="password" class="col-3 form-control">
<span class="error col-sm-4">{{ this.passwordErr }}</span>
</div>
<input type="submit" [disabled]="!isValid()" value="Login" class="login-button col-1">
</form>
我试过了:
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
providers: [
LoginComponent,
{ provide: RoutingService, useValue: MockRoutingService },
{ provide: AuthenticationService, useValue: MockAuthenticationService }
]
})
.compileComponents();
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
});
还:
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
providers: [
LoginComponent,
{ provide: RoutingService, useValue: MockRoutingService },
{ provide: AuthenticationService, useValue: MockAuthenticationService }
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
并且:
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
providers: [
LoginComponent,
{ provide: RoutingService, useValue: MockRoutingService },
{ provide: AuthenticationService, useValue: MockAuthenticationService }
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
LoginComponent
:
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
private password = '';
private email = '';
private emailErr = '';
private passwordErr = '';
constructor(private authService: AuthenticationService, private routingService: RoutingService) { }
ngOnInit() {
}
onSubmit() {
this.emailErr = '';
this.passwordErr = '';
const response: { ['emailValid']: boolean, ['passwordValid']: boolean } = this.authService.login(this.email, this.password);
const self = this;
setTimeout(() => {
if (response.emailValid === false) {
self.emailErr = '* Your username was incorrect, please try again.';
return;
} else if (response.passwordValid === false) {
self.passwordErr = '* Your password was incorrect, please try again.';
return;
}
self.routingService.route('home');
}, 300);
}
validateEmail() {
this.emailErr = '';
if (this.email === '') {
this.emailErr = '* Please enter your email.';
}
}
validatePassword() {
this.passwordErr = '';
if (this.password === '') {
this.passwordErr = '* Please enter your password.';
}
}
isValid() {
if (this.password === '' || this.email === '') {
return false;
} else if (this.emailErr !== '' || this.passwordErr !== '') {
return false;
}
return true;
}
}
我在这里想念什么?
解决方案
正如 nash11 指出的那样,您肯定需要LoginComponent
从提供者列表中删除 并且第一个beforeEach
应该运行async
.
我希望这样做您实际上应该得到一条不同的消息,告诉您 ngModel 不是<input/>
有两种方法可以让您的测试正常工作,这取决于您是否希望[{ngModel}]
像通常那样工作,或者您是否只想在对实际工作方式不感兴趣的地方对应用程序进行浅层测试[{ngModel}]
。
因此,如果您希望 ngModel 正常工作,则需要将其FormsModule
导入您的 TestBed。
如果您不介意 ngModel 有效,但它只是一个存在的属性,您可以NO_ERRORS_SCHEMA
在 TestBed 内部设置。
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent],
providers: [
{ provide: RoutingService, useValue: MockRoutingService },
{ provide: AuthenticationService, useValue: MockAuthenticationService }],
// imports: [FormsModule] // import the FormsModule if you want ngModel to be working inside the test
schemas: [NO_ERRORS_SCHEMA] // remove the FormsModule import and use that schema to only shallow test your component. Please refer to the official document for more information.
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
});
it('should be created', () => {
fixture.detectChanges();
expect(component).toBeTruthy();
});
});
这是一个有效的堆栈闪电战
推荐阅读
- javascript - 为什么将图像加载到画布并渲染它需要 crossorigin 属性?
- elasticsearch - Elasticsearch如何将选定的行项放在结果的顶部
- umbraco - Umbraco 分布式缓存不更新公共实例
- python - 如何将列表列表中的元组转换为列表
- virtocommerce - Virto Commerce - 主题与 Shopify 主题的兼容性
- python - 每个元素或整数索引的优点/缺点
- c++ - 如何在 gtk 中编写可选的客户端装饰?
- c# - 如何在 Xamarin 表单中获取三星健康步数
- ms-access - Table validation rule error: Unknown function 'Nz' in validation expression or default value on 'TableName'
- gitlab - How to get graphs to render in Mermaid + Jekyll / GitLab Pages?