如何以角度对剪贴板副本进行单元测试?

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

如何监视

clipboard.copy
方法? 对于

const clipboard = TestBed.inject(Clipboard);
spyOn(clipboard, 'copy').and.returnValue(true);

我收到警告

Argument of type '"copy"' is not assignable to parameter of type 'keyof Clipboard'.

我还尝试将其添加到导入和声明中:

这是

CopyToClipboardHost

class CopyToClipboardHost {
  public content = '';
  public attempts = 1;
  public copied = jasmine.createSpy('copied spy');
}
angular jasmine spy
4个回答
5
投票

我不知道为什么它在你的案例中不起作用,但我设法创建简单的测试用例并且它工作正常:

import {Component} from '@angular/core';
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
import {Clipboard} from '@angular/cdk/clipboard';
import createSpyObj = jasmine.createSpyObj;

@Component({
  selector: 'app-root',
  template: ''
})
export class SampleComponent {
  constructor(private clipboard: Clipboard) {
  }

  copySomething(): void {
    this.clipboard.copy('test');
  }
}

describe('SampleComponent', () => {
  let fixture: ComponentFixture<SampleComponent>;
  let component: SampleComponent;
  const clipboardSpy = createSpyObj<Clipboard>('Clipboard', ['copy']);

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [SampleComponent],
      providers: [{provide: Clipboard, useValue: clipboardSpy}]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SampleComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should call clipboard copy', () => {
    component.copySomething();

    expect(clipboardSpy.copy).toHaveBeenCalledWith('test');
  });
});

需要注意的一件事 - 不要将外部模块导入到

TestingModule
,因为您只想测试您的组件,而不是对所需的依赖项进行模拟/监视。


4
投票

我今天自己遇到了这个问题,它可能只是 Clipboard 类的不同/较新的实现。就我而言,正在使用

navigator.clipboard.writeText(text)
,所以我必须更换

spyOn(clipboard, 'copy').and.returnValue(true);

spyOn(clipboard, 'writeText').and.returnValue(true);

希望这对某人(如果不是你)有帮助。


3
投票

您可以导入 ClipboardModule 并将 Clipboard 提供给 TestBed。然后创建一个间谍复制方法。

import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard';

beforeEach(async () => {
    await TestBed.configureTestingModule({
        declarations: [ExampleComponent],
        imports: [ NoopAnimationsModule, ClipboardModule],
        providers: [ Clipboard ]
    }).compileComponents();
});

it('should copy to clipboard', () => {
    const clipSpy = spyOn(component.clipboard, 'copy').and.returnValue(true);
    component.copy();
    expect(clipSpy).toHaveBeenCalled();
});

0
投票

我遇到了同样的问题。我使用

jest
来测试我的 Angular 应用程序,而不是
jasmine
,所以我需要一个稍微不同的解决方案,但总的来说它反映了 Buczkowski 的解决方案上面:

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard';
import { FixedWidthTextBoxComponent } from './fixed-width-textbox.component';

describe('FixedWidthTextBoxComponent', () => {
  let component: FixedWidthTextBoxComponent;
  let fixture: ComponentFixture<FixedWidthTextBoxComponent>;

  // I can get along without a spy here. I don't know what I would have
  // done had I needed a spy, rather than a mock
  const mockWriteText = jest.fn();

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [FixedWidthTextBoxComponent, ClipboardModule],
      // I needed to pass an object here, rather than the mock function, 
      // because I'm using the "CdkCopyToClipboard" directive from Angular
      // CDK to handle the copying to the clipboard
      providers: [{ provide: Clipboard, useValue: { copy: mockWriteText } }],
    }).compileComponents();
    fixture = TestBed.createComponent(FixedWidthTextBoxComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('Copies data to the clipboard when the button is clicked', async () => {
    component.contents = 'blah blah blah';
    component.filename = 'testfile.txt';
    component.label = 'Test Label';
    fixture.detectChanges();

    const buttons: HTMLButtonElement[] =
      fixture.nativeElement.querySelectorAll('div button');
    let copyButton!: HTMLButtonElement;

    buttons.forEach((button) => {
      if (button.textContent === 'Copy') {
        copyButton = button;
      }
    });
    copyButton.click();
    expect(mockWriteText).toHaveBeenCalledWith(component.contents);
  });
});


© www.soinside.com 2019 - 2024. All rights reserved.