为什么这个按钮点击角度单元测试不起作用?



我有一个单元测试,我想测试是否在单击按钮时调用函数。但是我一直收到此错误:Expected spy archive to have been called.,我无法弄清楚为什么它不起作用。

我错过了什么或做错了什么吗?有关上下文,请参阅下面的代码。

这是我的考验

it('should call archive function on button click', async(() => {
spyOn(component, 'archive');
fixture.detectChanges();
component.project = rh.getProjects(1)[0];
dh.clickButton('Archive');
fixture.detectChanges();
expect(component.archive).toHaveBeenCalled();
}));

这是dh又名DOMHelper

clickButton(buttonText: string) {
this.findAll('button').forEach(button => {
const buttonElement: HTMLButtonElement = button.nativeElement;
if (buttonElement.textContent === buttonText) {
buttonElement.click();
}
});
}
findAll(tagName: string) {
return this.fixture.debugElement
.queryAll(By.css(tagName));
}

这是 html

<td data-label="Title">{{ project.title }}</td>
<td data-label="Owner">{{ getOwnerName(project.owner) }}</td>
<td data-label="Actions">
<button class="btn btn-primary" (click)="dashboard">Dashboard</button>
<button *ngIf="authService.firebaseAuth.auth.currentUser.uid == project.owner" class="btn btn-primary" (click)="archive">Archive</button>
</td>

这是组件.ts文件

import { Component, OnInit, Input } from '@angular/core';
import { Project } from 'src/app/models/project';
import { AuthService } from 'src/app/services/auth.service';
import { ProjectService } from 'src/app/services/project.service';
import { Router } from '@angular/router';
@Component({
selector: 'tr[app-joined-project-item]',
templateUrl: './joined-project-item.component.html',
styleUrls: ['./joined-project-item.component.css'],
})
export class JoinedProjectItemComponent implements OnInit {
@Input() public project: Project;
constructor(public authService: AuthService, public projectService: ProjectService, private router: Router) {}
ngOnInit(): void {
}
archive() {
this.projectService.updateArchivedStatusProject(this.project);
}
dashboard() {
this.router.navigate(['/projects/' + this.project.id + '/dashboard'])
}
getOwnerName(userId: string) {
return Object.values(this.project.members).find((member: any) => member['userId'] === userId)['name'];
}
}

更新

当我在检查是否调用服务函数的地方对其进行测试时,出现以下错误:Expected spy updateArchivedStatusProject to have been called with: *Project Object* but it was never called.

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [JoinedProjectItemComponent],
providers: [
{ provide: ProjectService, useClass: MockProjectService },
{ provide: AuthService, useClass: MockAuthService },
{ provide: Router, useValue: routerSpy }
]
}).compileComponents();
}));
it('should call archive function on button click', async(() => {
spy = spyOn(TestBed.get(ProjectService), 'updateArchivedStatusProject');
fixture.detectChanges();
component.project = rh.getProjects(1)[0];
dh.clickButton('Archive');
fixture.detectChanges();
expect(spy).toHaveBeenCalledWith(rh.projects[0]);
}));

我认为您在单击处理程序中缺少括号。应该是 :

<button (...) (click)="archive()">Archive</button>

编辑:

您认为这是测试错误而不是实际的简单错误这一事实表明您不信任您的测试。当它们在应用程序正常工作时失败很多时,可能会发生这种情况。这表明你编写测试的方式可能有问题。

我给出的一个建议是使你在测试中使用的工具尽可能明确。例如,可以将clickButton重写为以下内容:

clickButton(buttonText: string) {
const foundButtons = this.findAll('button')
.map(button => button.nativeElement)
.filter(button => button.innerText === buttonText);
if (foundButtons.length !== 1) {
fail(`Expected exactly one button with text "${buttonText}" but found ${foundButtons.length}`);
}
foundButtons[0].click();
}

最新更新