How to mock a class being imported from a npm module - react-native

I am importing a class via const { PaymentRequest } = require("react-native-payments"); and I am trying to mock the functions it exposes when it is instantiated. For example:
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS, OPTIONS);
paymentRequest.canMakePayments().then(res => {...})
I want to mock this and change the value coming back from the promise resolve so that I can test different scenarios from canMakePayments and other async functions the class exposes.

Here is the solution, you can use jest.mock method mock react-native-payments module manually.
index.ts:
const { PaymentRequest } = require('react-native-payments');
const METHOD_DATA = [
{
supportedMethods: ['apple-pay'],
data: {
merchantIdentifier: 'merchant.com.your-app.namespace',
supportedNetworks: ['visa', 'mastercard', 'amex'],
countryCode: 'US',
currencyCode: 'USD'
}
}
];
const DETAILS = {
id: 'basic-example',
displayItems: [
{
label: 'Movie Ticket',
amount: { currency: 'USD', value: '15.00' }
}
],
total: {
label: 'Merchant Name',
amount: { currency: 'USD', value: '15.00' }
}
};
const OPTIONS = {
requestPayerName: true
};
function main() {
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS, OPTIONS);
return paymentRequest.canMakePayment();
}
export { main, METHOD_DATA, DETAILS, OPTIONS };
main function is going to be tested.
index.spec.ts:
import { main, METHOD_DATA, DETAILS, OPTIONS } from './';
const { PaymentRequest } = require('react-native-payments');
jest.mock('react-native-payments', () => {
const PaymentRequestMocked = {
canMakePayment: jest.fn()
};
return {
PaymentRequest: jest.fn(() => PaymentRequestMocked)
};
});
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS, OPTIONS);
describe('main', () => {
beforeEach(() => {
paymentRequest.canMakePayment.mockReset();
});
it.each`
value | name
${'mocked value 1'} | ${'t1'}
${'mocked value 2'} | ${'t2'}
`(`$name`, async ({ value }) => {
paymentRequest.canMakePayment.mockResolvedValueOnce(value);
const actualValue = await main();
expect(actualValue).toEqual(value);
expect(paymentRequest.canMakePayment).toBeCalledTimes(1);
});
});
Unit test result with 100% coverage:
PASS src/stackoverflow/57565053/index.spec.ts
main
✓ t1 (5ms)
✓ t2 (1ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 3.03s, estimated 6s
Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57565053

Related

How can I test action in vuex with vue-test-utils and jest when this actions uses a globalProperties?

I'm really new at testing with vue-test-utis/jest, but I've stumbled upon an issue that I'm not sure how to test it. Could someone help me? I have an action in my store that uses a globalProperties and when I try to use it in tests it's not working.
Basically this is my test:
describe('test: actions', () => {
it('buildReservationsTableData', () => {
let data = actions.buildReservationsTableData(mockDataBefore);
expect(data).toEqual(tableData);
})
})
And this is the action that I'm trying to write a test:
buildReservationsTableData(channelsData) {
let renderTable = ant_table.getRender('table');
if (!channelsData) {
return renderTable.handle([], []);
}
let data = [],
sortable = [],
headers = {
"code" : "Code",
"guestName" : "Guest name",
"checkin" : "Check-in",
"checkout" : "Check-out",
"nights": "Nights",
"ratePlan": "Rate plan",
"roomType": "Room Type",
"totalAmount": "Total amount",
"channel": "Channel",
"status": "Status",
"date": "Date"
},
slots = {};
for (let idx in channelsData){
if (Object.prototype.hasOwnProperty.call(channelsData[idx], "sentToPms")) {
headers.sentToPms = "Sent to PMS";
break;
}
}
for (let idx in channelsData) {
let record = {
id : channelsData[idx].code,
child : channelsData[idx].teste
};
for (let key in headers) {
record[key] = channelsData[idx][key];
if (key == "totalAmount"){
record[key] = global.dashboards.$filters.currency(channelsData[idx][key]);
}
sortable.push(key);
if (key == 'status' || key == 'sentToPms'){
slots[key] = {customRender : 'format'};
}
}
data.push(record);
}
return renderTable.handle(headers, data, {"sortable": sortable, slots: slots});
},
My problem is that the test suit doesn't know what is global.dashboards.$filters.currency, my globalProperties. I get this error:
● test: actions › buildReservationsTableData
TypeError: Cannot read properties of undefined (reading '$filters')
84 | record[key] = channelsData[idx][key];
85 | if (key == "totalAmount"){
> 86 | record[key] = global.dashboards.$filters.currency(channelsData[idx][key]);
| ^
87 | }
88 |
89 | sortable.push(key);
On my jest.init.js file I have this config, but the action is not aware of that.
import { config } from "#vue/test-utils";
config.global.mocks = {
$filters: {
translate: (msg) => msg,
currency: (currency) => currency
},
$t: (text) => text
}
How do I fix it? Thanks in advance.
Judging by the error it your dashboards object which is not defined.
I don't know how you create it or what it is, but if you want to try to mock in Vue-test-utils config file please note that global doesn't seem to be a valid config option, you might want to try:
config.mocks = {
global: {
dashboards: {
$filters: {
translate: (msg) => msg,
currency: (currency) => currency
},
$t: (text) => text
}
}
}
Alternatively Jest provide a way to define global variables that need to be available in all test in jest.config.js:
// globals: {},

Why did the foreign key constraint fail on the column `postId`?

Why did the foreign key constraint fail on the column: postId? How can I fill the prisma studio with the same postId values?
Faker create table git example
Manual filling git example
enter image description here
images: {
create: [
{
imagePuth: faker.image.image(),
postId: faker.datatype.number({ min: 1, max: 7 }),
},
],
},
Environment variables loaded from .env
Running seed command `ts-node prisma/seed.ts` ...
Start seeding ...
PrismaClientKnownRequestError:
Invalid `prisma.user.create()` invocation in
Z:\spa\project\server\prisma\seed.ts:18:36
15 async function main() {
16 console.log(`Start seeding ...`);
17 for (let i = 0; i < 7; i++) {
→ 18 const user = await prisma.user.create(
Foreign key constraint failed on the field: `postId`
at cb (Z:\spa\project\server\node_modules\#prisma\client\runtime\index.js:38537:17)
at async main (Z:\spa\project\server\prisma\seed.ts:18:18) {
code: 'P2003',`enter code here`
clientVersion: '3.3.0',
meta: { field_name: 'postId' }
}
An error occured while running the seed command:
Error: Command failed with exit code 1: ts-node prisma/seed.ts
enter image description here
images: {
create: [
{
imagePuth: faker.image.image(),
postId: 1,
},
],
},
console.log('postId ' + faker.datatype.number({ min: 1, max: 7 }));
console.log(`Created user with id: ${user.id}`);
Running seed command `ts-node prisma/seed.ts` ...
Start seeding ...
postId 7
Created user with id: 1
postId 3`enter code here`
Created user with id: 2
postId 5
Created user with id: 3
postId 7
Created user with id: 4
postId 5
Created user with id: 5
postId 5
Created user with id: 6
postId 7
Created user with id: 7
Seeding finished.
The seed command has been executed.
images: {
create: [
{
imagePuth: faker.image.image(),
postId: 2,
},
],
},
enter image description here
Thank you I did so
Tasin Ishmam
import { PrismaClient, Prisma } from '#prisma/client';
//import faker from 'faker';
const prisma = new PrismaClient();
const faker = require('faker');
async function main() {
console.log(`Start seeding ...`);
for (let i = 0; i < 7; i++) {
const user = await prisma.user.create({
data: {
email: faker.internet.email(),
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
avatar: faker.image.avatar(),
},
});
console.log({ user });
}
for (let i = 0; i < 7; i++) {
const post = await prisma.post.create({
data: {
title: faker.name.title(),
content: faker.lorem.paragraphs(),
userId: faker.datatype.number({ min: 1, max: 7 }),
},
});
console.log({ post });
}
for (let i = 0; i < 14; i++) {
const image = await prisma.image.create({
data: {
imagePuth: faker.image.image(),
postId: faker.datatype.number({ min: 1, max: 7 }),
userId: faker.datatype.number({ min: 1, max: 7 }),
},
});
console.log({ image });
}
console.log(`Seeding finished.`);
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});

How Test e2e Nestjs API with GRAPHQL

When I create my Owner via graphql-playground it works fine,
but my test fail and response me that 'body.data.createOwner is undefined', there no data.
// owner.e2e.spec.ts
describe('Owner test (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
imports: [
GraphQLModule.forRoot({
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
}),
OwnerModule,
DatabaseModule
]
}).compile();
app = moduleRef.createNestApplication();
await app.init();
});
afterAll(async () => {
await app.close();
})
const createOwnerQuery = `
mutation createOwner($OwnerInput: OwnerInput!) {
createOwner(ownerInput: $OwnerInput) {
_id
name
firstname
email
password
firstsub
expsub
createdAt
updatedAt
}
}
`;
let id: string = '';
it('createOwner', () => {
return request(app.getHttpServer())
.post('/graphql')
.send({
operationName: 'createOwner',
variables: {
OwnerInput: {
name: 'adar',
firstname: 'adar',
email: 'adar#test.com',
password: 'testing',
firstsub: '2020-08-14',
expsub: '2020-07-13'
}
},
query: createOwnerQuery,
})
.expect(({ body }) => {
const data = body.data.createOwner <-- test fail at this line
id = data._id
expect(data.name).toBe(owner.name)
expect(data.email).toBe(owner.email)
expect(data.firstsub).toBe(owner.firstsub)
})
.expect(200)
})
// Output terminal
FAIL test/owner.e2e-spec.ts (9.567 s)
Owner test (e2e)
✕ createOwner (79 ms)
● Owner test (e2e) › createOwner
TypeError: Cannot read property 'createOwner' of undefined
98 | })
99 | .expect(({ body }) => {
> 100 | const data = body.data.createOwner
| ^
101 | id = data._id
102 | expect(data.name).toBe(owner.name)
103 | expect(data.email).toBe(owner.email)
at owner.e2e-spec.ts:100:40
at Test._assertFunction (../node_modules/supertest/lib/test.js:283:11)
at Test.assert (../node_modules/supertest/lib/test.js:173:18)
at Server.localAssert (../node_modules/supertest/lib/test.js:131:12)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 9.645 s, estimated 10 s
Ran all test suites.
My problem was from CLI plugin which generate automatically nullable Graphql fields without putting the #Field decorator in my ObjectType.
The creator of nest gave a trick about this issue.
--> https://github.com/nestjs/graphql/issues/810
but this doesn't works for me, so I simply added "#Field" decorator to all attributs in my model #ObjectType().

Using Ramda to accumulate sum of values in objects

I have an object like this:
obj = {
'key1': {'prop1': 123,'prop2':345},
'key2': {'prop1': 673,'prop3':642}
}
I would like to have the following result:
result = {'prop1': 796, 'prop2':345, 'prop3':642}
That is, I want a single object that has all properties. I have a function like this:
Object.values(obj).reduce((acc,currentObj) => {
const props = Object.keys(currentObj);
props.forEach(prop => {
if(prop in acc){
acc[prop] += currentObj[prop]
} else {
acc[prop] = currentObj[prop]
}
})
return acc
}, {})
I believe this works fine, but is there any way to do the same with RamdaJS?
A simple reduce function would do that.
const fn = R.pipe(
R.values,
R.reduce(R.mergeWith(R.add), {}),
);
//--
const data = {
key1: { prop1: 123, prop2: 345 },
key2: { prop1: 673, prop3: 642 },
};
console.log(
fn(data),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js" integrity="sha256-xB25ljGZ7K2VXnq087unEnoVhvTosWWtqXB4tAtZmHU=" crossorigin="anonymous"></script>

how to deal with testing that uses uuid inside the component

I try to test my component that has a function to add an item to the array and each of those items has UUID property but I get this error when I try to run the unit test for that.
TypeError: Cannot read property 'v1' of undefined
const basicDataItem = {
> 380 | id: this.$uuid.v1()
How can I test the code that uses UUID like in this case?
edit:
this is the function that I want to test
addDataItem(key) {
const basicDataItem = {
id: this.$uuid.v1(),
units: '',
price: '',
label: '',
};
this.editableData[key].push(basicDataItem);
}
Here is a unit test solution for your case:
index.js:
export class SomeClass {
editableData = {
jest: []
};
$uuid = {
v1() {
return 'real uuid';
}
};
addDataItem(key) {
const basicDataItem = {
id: this.$uuid.v1(),
units: '',
price: '',
label: ''
};
this.editableData[key].push(basicDataItem);
}
}
index.spec.js:
import { SomeClass } from './';
describe('SomeClass', () => {
test('should add data item', () => {
const someClassInstance = new SomeClass();
const uuidv1Spy = jest.spyOn(someClassInstance.$uuid, 'v1').mockReturnValueOnce('fake uuid');
someClassInstance.addDataItem('jest');
expect(uuidv1Spy).toBeCalledTimes(1);
expect(someClassInstance.editableData).toEqual({ jest: [{ id: 'fake uuid', units: '', price: '', label: '' }] });
});
});
Unit test result with coverage report:
PASS src/stackoverflow/58710736/index.spec.js
SomeClass
✓ should add data item (14ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 88.89 | 100 | 66.67 | 87.5 | |
index.js | 88.89 | 100 | 66.67 | 87.5 | 7 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.909s, estimated 6s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58710736