angular unit test: How to mock up a FileList in Jest?
I'm trying to create a Jest unit test for an field used for uploading files.
I would like to mock up a FileList object containing image files.
uploadImage(files: FileList) {
this.uploadError = '';
if (files.length <= 0) {
return;
}
const file = files[0];
if (/^[A-Za-z0-9!-_.'()]/.test(file.name)) {
this.uploadError = 'Invalid characters...';
return false;
}
if (file.size >= LIMIT_SIZE_IMAGE) {
this.uploadError = 'Limit size exceeded...';
return false;
}
this.uploadService.uploadImage(file);
}
Since FileList is readonly, I can't create it by calling
new FileList([...files])
Which brings me to my question - how does one create a testable mock object? Any ideas?
See also questions close to this topic
-
How to set PrimeNG ConfirmDialog widget width in logic layer?
I am using "primeng": "^11.2.0" with following working ConfirmDialog code
this.confirm.confirm({ header: 'Announcement', message: this.userCompany.announcement.promptMsg, acceptLabel: this.userCompany.announcement.labelOK? this.userCompany.announcement.labelOK:'OK', rejectLabel: this.userCompany.announcement.labelDoNotShowAgain? this.userCompany.announcement.labelDoNotShowAgain:'Do not show again', accept: () => { console.log('accepted') }, reject: () => { console.log('rejected') } });
Here the result in mobile layout. It doesn't seems 'responsive' and mobile friendly.
When i refer back official doc, it seems like the 'style' property is available. I changed my code to include 'style' property (as below), it prompted error
this.confirm.confirm({ header: 'Announcement', message: this.userCompany.announcement.promptMsg, style: {width: '50vw'}, acceptLabel: this.userCompany.announcement.labelOK ? this.userCompany.announcement.labelOK : 'OK', rejectLabel: this.userCompany.announcement.labelDoNotShowAgain ? this.userCompany.announcement.labelDoNotShowAgain : 'Do not show again', accept: () => { console.log('accepted') }, reject: () => { console.log('rejected') } });
Error
error TS2345: Argument of type '{ header: string; message: any; style: { width: string; }; acceptLabel: any; rejectLabel: any; accept: () => void; reject: () => void; }' is not assignable to parameter of type 'Confirmation'. Object literal may only specify known properties, and 'style' does not exist in type 'Confirmation'. 117 style: {width: '50vw'},
So how could i make the confirmDialog box look nicer in mobile view (tweak the style in logic, not template file).
Thanks for the helps.
-
Angular get value in the app component coming from a map
I tried several ways and I was unable to print the valueM, ValueR and product in my app.component.html Can anyone give me a solution or tip for me to proceed? thank you very much
app.component.ts
forkJoin( this.service1.method1(filter1), this.service2.methodo2(filter2), ).subscribe(data => { const cc = data[0] || []; console.log(cc); const pp = data[1] || []; const arrayIdsProducts = pp.map(element => element.product); const sc = cc.filter(elemente => arrayIdsProducts.includes(elemente.product)); console.log(sc); this.valuesC = sc.map(e => ({ valueM: e.valueM, valueR: e.valueR, product: e.product }));
Console.log
[{…}] 0: codigoSistemaFormatado: "0002.0004", id: 119 product: 5, productName: "T-SHIRT XYZ BLUE XL"
[{…}] 0: product: 5, ValueM: 31.053333333333335, valorR: 49.9
app.compontent.html
<table formArrayName="productos" class="table table-bordered table-striped"> <thead> <tr> <th width="5%" class="text-center">ValueM</th> <th width="30%" class="text-center">ValueR</th> <th width="9%" class="text-center">Produte</th> <th width="7%"></th> </tr> </thead> <tr [formGroupName]="i" *ngFor="let item of formGroup.controls.produtos.controls; let i=index; last as isLast; first as isFirst"> <td> {{i+1}} </td> <input hidden formControlName="unidadeNome"> <input hidden formControlName="codigoSistemaFormatado"> <input hidden formControlName="ValueM"> > <input hidden formControlName="valueR"> <td> <app-vo-filtro-produtos (valueSelected)="onProductChanged($event, i)" [showLabel]="false" [multiple]="false" formControlName="produto" [itens]="produtos[i]"></app-vo-filtro-produtos> </td> <td> <input type="text" value="{{produtos[i].codigoSistemaFormatado}}" class="form-control" disabled="true"> </td> <td> <input type="text" value="{{produtos[i].unidadePrincipal?.unidade.sigla}}" class="form-control" disabled="true"> </td> <td> <input type="text" value="{{valueM HERE}}" class="form-control" disabled="true"> </td> <td> <input type="text" value="{{valueR HERE}}" class="form-control" disabled="true"> </td> </td> </tr> </table> </form>
-
How to avoid child route trigger ngOnInit of parent component?
I have an angular module with the next structure
Container component.
-Child 1.
-Child 2.
-Child 3.
When the user navigate between the children route the ngOnInit of the Container component is being triggered. How can avoid this?
And sorry my inglish stinks
-
How to mock Currency Singleton Object
For Unit Test, I am trying to mock the getInstance method in currency class java
whenever(getCurrency).thenReturn(Currency.getInstance("USD"))
But this is not working
-
unable to see the updated DOM in spec after its getting modified
I am writing a functional spec using Mocha/JSDOM and asserting with 'chai'.
The use case is when I call the function: updateContent,
- It would internally call another function that would fetch some HTML content.
- Later I would process that HTML content and add it to the existing DOM elements.
This is working fine when I run on the server but the issue is when I try to write a spec, not able to see the updated DOM. I checked the updateContent function by placing the console statement and I see the updated content but once the control transferred to the spec function, I am seeing the original DOM that is added to JSDOM.
This is written using Typescript, js combination, and JQuery for DOM operations
Could you please help me with what am I missing here? Any suggestion/info would be helpful. I tried using global while accessing
updateContent function available in helper.js file
function updateContent(year, fetchAge) { Promise.all([fetchAge("age")]).then((data) => { console.log("DOM before update ="+$('html').html()); data = data[0].replace(/{{age}}/g, year); $('.mybenifits .content').html(data); console.log("DOM after update ="+$('html').html());//Able to see the updated DOM console.log("$('.mybenifits .content').html="+global.$('.mybenifits .content').html()); }).catch((error) => { console.log(" ******* Error while fetching age info"); }); }
Spec Code snippet: helper.test.js
const expect = require('chai').expect; const assert = require('chai').assert; const sinon = require('sinon'); const { JSDOM } = require('jsdom'); const { updateContent } = require('../../main/webpack/common/helper.js'); describe('Helper - Example', () => { it('should update the content', () => { let htmlStr = '<!doctype html><html><body><div class="mybenifits"><div class="content"></div></div></body></html>'; const jsdom = new JSDOM(htmlStr, { url: 'http://localhost/', }); //Setting Global variables - start global.window = jsdom.window; global.document = jsdom.window.document; global.$ = require('jquery'); //Setting GLobal variables - end //Mocking fetchAge function function fetchAge(featurename) { return '<p id="fcontent">Current Age is {{age}}</p>'; } updateContent("2020",fetchAge); console.log("Total html file ="+$('html').html()); //expect($('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>'); //expect(global.$('.mybenifits .content').html()).to.be.equal('<p id="fcontent">Current Age is 2020</p>');//Not working even if I use global }); });
-
Testing Controller and Service in Jest
I'm fairly new to Jest and have been trying (with no luck) to figure out how to write tests for my controller. I'm not sure how to write the test as it calls another function. It would be great if I could get pointed in the right direction at least. Thanks in advance.
controller.ts
import * as Services from './services'; export async function GetCountriesList(req: Request, res: Response): Promise<void> { const response = await Services.GetCountriesList(); res.status(response.code).json({ status: response.status, message: response.message, count: response.count, data: response.data }); }
service.ts
import db from '../../modules/db'; import { DBGenericDataResponse } from '../../types/models'; export async function GetCountriesList(): Promise<DBGenericDataResponse> { const lQuery = 'somquery'; const responseMessage: DBGenericDataResponse = { code: 200, status: 'ok', message: '', count: 0, data: [], error: '' }; try { const dbResult = await db.query<any>(lQuery); responseMessage.message = 'Countries returned'; responseMessage.count = dbResult.rows.length; responseMessage.data = dbResult.rows; } catch (err) { responseMessage.code = 400; responseMessage.status = 'error'; responseMessage.message = 'Error retrieving Countries List'; responseMessage.error = err; } return responseMessage; }
-
Jest mock middleware response
I am trying to mock a middleware response, and i am trying to use
jest.spyOn()
but can't seem to get it workingMy controller.ts has the following
import someMiddleware from '../someMiddleware; .... .... this.route.post('/getData', someMiddleware, setValue)
In someMiddlware.ts
//making a fetch call based on data in req.body ..... const data = await fetchData(url, data) next() .....
In my test file controller.test.ts
describe('Test Data', () => { beforeEach(() => { someMiddlewareSpyOn = jest.spyOn(meddelware, "someMiddleware"); }); afterEach(() => { jest.resetModules(); jest.resetAllMocks(); }); it('response status should be a 200', async () => { someMiddlewareSpyOn.mockResolvedValue({data:[].....}); const res = await request(app.getServer()) .post('/getData'); expect(res.status).toBe(200); }) });
The above does not work, looking for assistance on how to do this.
-
Warning: <TEXT /> is using incorrect casing
console.error node_modules/react-dom/cjs/react-dom.development.js
Warning:
<TEXT />
is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.I have the issue with Jest and react-pdf
In the component where I'm using the react-pdf components this is written as:
<Text>
, but when performing the test it's appearing as<TEXT>
My component:
const HeaderPDF: React.FC<Props> = (props: Props) => { return ( <View style={styles.headerContainer} fixed> <View style={styles.headerTop}> <Text style={styles.textBoldTopHeader}> "Some text" </Text> <View style={styles.headerTopInputContainer}> <View style={styles.headerTopInputTextContainer}> <Text style={styles.textInputTopHeader}>Route</Text> </View> <View style={styles.inputSmall} /> </View> </View> </View> ); };
The test:
import React from 'react'; import { render } from 'tests/support/customRender'; import HeaderPDF from ../../HeaderPDF'; describe('HeaderPDF', () => { it('Renders a HeaderPDF component successfully', () => { const { container } = render( <HeaderPDF someProps /> ); expect(container).toMatchSnapshot(); }); });
-
Angular unit testing functions
I have just started exploring unit testing in angular. I have a function in .ts file
onValueChange(val: number): void { this.formGroup.get(this.controlName).setValue(val); }
I am trying to test if the controlName has the value passed in the onValueChange parameters
I tried this in the spec.ts file
it('form value should update from form changes', fakeAsync(() => { onValueChange(5); expect(component.formGroup.get(component.controlName)).toEqual(5); })); function onValueChange(val: number): void { component.formGroup.get(component.controlName).setValue(val); }
what am I doing wrong
- Pass data from one it block to another
-
How to properly write unit tests for a logout service using jasmine?
I'm still new to unit tests so I wonder if anyone help me with this small task. I'm using angular 8 with jasmine.
This is my service for the logout:
import {Injectable} from '@angular/core'; @Injectable({ providedIn: 'root' }) export class LogoutService { logout() { const {protocol, hostname, port: locationPort} = window.location; const port = locationPort ? `:${locationPort}` : ''; window.location.href = `/oauth/logout?redirect=${protocol}//${hostname}${port}`; } }
This is my test that I'm trying:
import { LogoutService } from './logout.service'; describe('LogoutService', () => { let service; beforeEach(() => { service = new LogoutService(); }); it('should run #logout()', async () => { let path = '/oauth/logout?redirect' service.logout(); expect(window.location.href).toEqual(jasmine.objectContaining(path)) }); });
So far I'm trying to test if windows location has the protocol & the hostname & the port.
Thank you in advance.