为什么这个按钮点击的Angular单元测试不能用?

问题描述 投票:0回答:1

我有一个单元测试,我想测试一个函数是否在按钮点击时被调用。但我一直收到这个错误。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>

这是component.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]);
}));
angular typescript karma-jasmine
1个回答
1
投票

我想你在点击处理程序中缺少了括号。应该是:

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

EDIT:

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

我给出的一个建议是,让你在测试中使用的工具尽可能的明确。例如 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();
}
© www.soinside.com 2019 - 2024. All rights reserved.