5

How to spy on clipboard.copy method? For

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

I get warning that

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

enter image description here

I've also tried to add this to imports and declarations: I've also tried to add this to imports and declarations

This is CopyToClipboardHost

class CopyToClipboardHost {
  public content = '';
  public attempts = 1;
  public copied = jasmine.createSpy('copied spy');
}
Sakén
  • 197
  • 1
  • 12
  • Can you provide code for `Clipboard`? – Buczkowski Oct 13 '21 at 12:44
  • In the constructor I have private clipboard: Clipboard It's a standard Angular Clipboard class https://material.angular.io/cdk/clipboard/overview – Sakén Oct 13 '21 at 13:08
  • I've tried to use the information provided here https://github.com/angular/components/blob/master/src/cdk/clipboard/copy-to-clipboard.spec.ts But doesn't work – Sakén Oct 13 '21 at 13:12

3 Answers3

4

I don't know why it didn't work within your case but I manage to create simple test case and it's working properly:

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');
  });
});

One thing to note - do not import external modules to TestingModule as you want to test only your component rather do mock/spy upon required dependencies.

Buczkowski
  • 2,296
  • 12
  • 18
  • I've added the imports and for this: const clipboardSpy = createSpyObj('Clipboard', ['copy']); I get this is VsCode: Type '"copy"' is not assignable to type 'keyof Clipboard'.ts(2322). And this in WebStorm: TS2322: Type '"copy"' is not assignable to type '"readText" | "writeText" | "addEventListener" | "dispatchEvent" | "removeEventListener"'. Which IDE do you use? Maybe something is wrong with my IDEs – Sakén Oct 18 '21 at 14:14
  • @Sakén I'm using Webstorm, are you sure that `Clipboard` you did import is right one and not something else? – Buczkowski Oct 19 '21 at 07:28
  • It's from import { Clipboard } from '@angular/cdk/clipboard'; – Sakén Oct 19 '21 at 07:31
  • @Sakén hard to say, it should work but instead your IDE think is some other `Clipboard`. – Buczkowski Oct 19 '21 at 07:57
  • Worked perfectly, thank you! – HanClinto Nov 23 '21 at 15:46
2

You can import ClipboardModule and provide Clipboard in to TestBed. Then create a spy on copy method.

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();
});
Uliana Pavelko
  • 2,824
  • 28
  • 32
2

I ran into this issue myself today, and it may have just been a different/newer implementation of the Clipboard class. In my case navigator.clipboard.writeText(text) was being used, so I had to replace

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

with

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

Hope this helps someone if not you.