How to write the unit testing for the file upload method in the Angular 7 (or 2+)
12,796
Solution 1
For the 100% code coverage of the mentioned section, I have added below 2 test cases. This works for me.
it('should upload the file - checkFileExist = true', () => {
spyOn(component, 'checkFileExist').and.returnValue(true);
spyOn(postalService,'importPostalCodes').and.callThrough();
component.importFile();
expect(postalService.importPostalCodes).toHaveBeenCalled();
});
it('should upload the file - checkFileExist = false', () => {
spyOn(component, 'checkFileExist').and.returnValue(false);
spyOn(postalService,'importPostalCodes').and.callThrough();
component.importFile();
expect(postalService.importPostalCodes).toHaveBeenCalledTimes(0);
});
Solution 2
A simple way to test file upload and check model value set.
.html
<input (change)="onFileSelected()" #fileInput type="file" id="file">
.ts
uploadedFile : any
onFileSelected() {
const inputNode: any = document.querySelector('#file');
this.uploadedFile = inputNode.files[0];
}
spec.ts
it('should detect file input change and set uploadedFile model', () => {
const dataTransfer = new DataTransfer()
dataTransfer.items.add(new File([''], 'test-file.pdf'))
const inputDebugEl = fixture.debugElement.query(By.css('input[type=file]'));
inputDebugEl.nativeElement.files = dataTransfer.files;
inputDebugEl.nativeElement.dispatchEvent(new InputEvent('change'));
fixture.detectChanges();
expect(component.uploadedFile).toBeTruthy()
expect(component.uploadedFile).toBe('test-file.pdf')
});
it('file change event should arrive in handler', () => {
const element = fixture.nativeElement;
const input = element.querySelector('#file');
spyOn(component, 'onFileSelected');
input.dispatchEvent(new Event('change'));
fixture.detectChanges();
expect(component.onFileSelected).toHaveBeenCalled();
});
Comments
-
Helphin almost 2 years
I'm trying to write the unit testing for the file upload method in the angular 7. Getting the below error in the testing window. I'm new for angular unit testing. Could someone help, How to add mock files to get the full code coverage?
TypeError: Cannot set property 'value' of undefined
Here is my unit test code (spec file),
describe('ImportComponent', () => { let component: ImportComponent; let fixture: ComponentFixture<ImportComponent>; let element; beforeEach( async(() => { TestBed.configureTestingModule({ imports: [ HttpClientModule, RouterTestingModule ], declarations: [ ImportComponent ] }).compileComponents(); }) ); beforeEach(() => { fixture = TestBed.createComponent(ImportComponent); component = fixture.componentInstance; element = fixture.nativeElement; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); it('should upload the file', () => { component.importFile(); const inputEl = element.querySelector('#postal_file'); const fileList = { 0: { name: 'foo', size: 500001 } }; inputEl.value = { target: { files: fileList } }; inputEl.dispatchEvent(new Event('change')); }); });
Method in the component
importFile() { const inputEl: HTMLInputElement = this.el.nativeElement.querySelector('#postal_file'); const fileCount: number = inputEl.files.length; const formData = new FormData(); if (fileCount > 0) { formData.append(this.postalFileName, inputEl.files.item(0)); this.postalService.importPostalCodes(formData).subscribe((data) => { this.result = data; }); } }
and the HTML,
<div class="file-import"> <form action="" method="post" encType="multipart/form-data"> <label for="postal_file">Choose File</label> <input type="file" name="postal_file" id="postal_file"> <button type="button" (click)="importFile()">Import</button> </form> </div>
The unit test is not covered all the code as shown in the below image, please help , how to ge the 100% code coverage.
-
Abhishek Singh almost 3 yearsAwesome..! really you answer worth 100 likes..!!
-
sharpshooter over 2 yearsHello @adrita, your answer helped me a lot, but how can I pass an actual csv file with valid data to cover the other lines in main component code?