Not sure if this is still relevant but I had this issue today and solved it. Just leaving this here incase someone else has the same issue.
This is the method I was attempting to test inside the directive
@HostListener('drop', ['$event'])
onDrop(evt: any) {
evt.preventDefault()
evt.stopPropagation()
this.fileOver = false
const files = evt.dataTransfer.files
if (files.length > 0) {
this.fileDropped.emit(files)
}
}
I created the test suite as per Angulars documentation, creating a fake component with the directive added to a div element.
@Component({
template: `<div id="file-drop-area" filedrop (fileDropped)="handleDrop($event)"></div>`
})
class TestFileDropComponent {
handleDrop(files: FileList) {}
}
describe('FileDropDirective', () => {
let directive: FileDropDirective
let component: TestFileDropComponent
let fixture: ComponentFixture<TestFileDropComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TestFileDropComponent, FileDropDirective ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(TestFileDropComponent);
component = fixture.componentInstance
fixture.detectChanges();
})
})
Then I created a new DataTransfer instance, pushed my fake file to the items array and passed the DataTransfer instance to the event which was then dispatched.
it('should verify the directive recognises a drop event', () => {
spyOn(component, 'handleDrop')
const el: HTMLElement = fixture.nativeElement
const fileDropArea: HTMLDivElement = el.querySelector('#file-drop-area')!
const file = new File([''], 'dummy.txt')
const dataTransfer = new DataTransfer()
dataTransfer.items.add(file)
const event = new DragEvent("drop", { dataTransfer })
fileDropArea.dispatchEvent(event)
fixture.detectChanges()
expect(component['handleDrop']).toHaveBeenCalledWith(dataTransfer.files)
})