I have an Angular 6 app that has an "export to CSV" button that when clicked, runs a method on the component that generates the CSV text to be downloaded. The file is then downloaded with the following code:
const tempLink = document.createElement('a');
tempLink.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
tempLink.target = '_blank';
tempLink.download = 'export.csv';
tempLink.click();
How would I unit test clicking the "Export to CSV" button without triggering an actual download?
Would the only approach be to create the link in the HTML (not dynamically) and then have a Jasmine spy on the click event of the link?
Create an Angular project with jasmine and karma By doing this, the jasmine and karma configuration is resolved for us. Install and create a new project with angular-cli: Install npm -g @angular/cli. Ng new angular-unit-testing angular unit-testing.
Jasmine is a behavior development testing framework. Unit tests are written using Jasmine and are run to see if individual parts of an application are working correctly. As a result, unit tests will either pass or fail depending on if the code is working correctly or has a bug.
You can use the Jasmine spy functions (spyOn, spyOnProperty, jasmine.createSpy, jasmine.createSpyObj) in combination with the and methods to spy on and mock behavior.
In this case you can mock document.createElement()
to return a spy object that you can use to verify that the correct properties get set and click()
gets called.
Here is a working example:
example.component.ts
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-example',
template: '<div><button (click)="download()">Download Csv</button></div>'
})
export class ExampleComponent implements OnInit {
constructor() { }
ngOnInit() { }
download() {
const csvContent = this.generateCsv();
const tempLink = document.createElement('a');
tempLink.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvContent);
tempLink.target = '_blank';
tempLink.download = 'export.csv';
tempLink.click();
}
private generateCsv() {
return 'ID,Name\n1,abc\n2,def\n';
}
}
example.component.spec.ts
import { ExampleComponent } from './example.component';
describe('ExampleComponent', () => {
it('should download the csv file', () => {
// create spy object with a click() method
const spyObj = jasmine.createSpyObj('a', ['click']);
// spy on document.createElement() and return the spy object
spyOn(document, 'createElement').and.returnValue(spyObj);
const comp = new ExampleComponent();
comp.download();
expect(document.createElement).toHaveBeenCalledTimes(1);
expect(document.createElement).toHaveBeenCalledWith('a');
expect(spyObj.href).toBe('data:text/csv;charset=utf-8,ID,Name%0A1,abc%0A2,def%0A');
expect(spyObj.target).toBe('_blank');
expect(spyObj.download).toBe('export.csv');
expect(spyObj.click).toHaveBeenCalledTimes(1);
expect(spyObj.click).toHaveBeenCalledWith();
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With