Move arrow function to another exported function - node.js

I have a problem. I want to clean my code and put function to another file but I always get an error:
getMe is not a function
why? I want to use it in already exported function getExchangeRateIntent. Is that causing a problem?
outside.js
const getRate = (base) => {
console.log('My base currency is '+base);
};
module.exports = {getRate};
getRate.js
const getMe = ('./outside.js');
module.exports = {
'getExchangeRateIntent': (conv, parameter) => {
const currencyBase = (parameter['currencyBase']);
const currencyTarget = (parameter['currencyTarget']);
const amount = (parameter['amount']);
console.log(currencyBase);
console.log(currencyTarget);
console.log(amount);
getMe('USD');
conv.ask('nothing');
},
};

module.exports = {getRate}; you are exporting an object. With your import:
const getMe = ('./outside.js');
you are importing an object. So this is not a function. This is not a proper import also.
For proper import you could write something like this:
import {getRate} from './outside.js;
And use it like this:
getRate('USD');
Or if you want to use require:
const getMe = require('./outside.js');
And then you can call function like this in second case:
getMe.getRate('USD')

Related

How to spyOn an internal static function call?

I have the following event handler and I want to test that updateOrAddNew is being called.
const { Events } = require('client');
const User = require('../models/User');
module.exports = {
name: Events.MemberAdd,
async execute(member) {
User.updateOrAddNew(member);
}
}
I've written the following test:
import {it, expect, vi } from 'vitest';
import User from '../models/User';
import memberAdd from './memberAdd';
it('calls updateOrAddNew on memberAdd', async () => {
const spy = vi.spyOn(User, 'updateOrAddNew').mockReturnValue(true);
User.updateOrAddNew = spy;
const member = {...};
await memberAdd.execute(member);
expect(spy).toBeCalled();
});
I've tried numerous different syntax but the spy is never called. updateOrAddNew is a static method. How can I test whether it's being called when memberAdd.execute is run?
I'm pretty new to testing so any help would be appreciated.
What if you declare in that file globally like this:
jest.spyOn(User, 'updateOrAddNew').mockReturnValue(true);
This should update any usage of this method with mock

How to break a single node.js file into many?

Hi,
I have an app on node.js which consists of a single file app.js that looks like this:
//variables
app = require("express")();
//many more variables here
//functions
function dosomething {}
//many more functions here
but since its getting a little too long I would like to break it into several files, one for variables only (variables.js) and another one for functions only (functions.js) and load them from app.js like this like when you do it with php
//variables
include(variables.js);
//functions
include(functions.js);
is it even possible to do that? Or I have to include everything in one single file like I do now?
Thank you.
You can use Module.Export to export a separate file, and import it into another file using the require statement. Please check here for details:
https://www.geeksforgeeks.org/import-and-export-in-node-js/
Happy Learning :-)
Importing API Endpoints
You can do this by using app.use(...) and point each endpoint to a specific file like so:
const express = require("express");
const app = express();
// User Functions
app.use("/api/user", require("./routes/api/user"));
//Orders functions
app.use("/api/orders/", require("./routes/api/orders"));
/**
* Express Server Init
*/
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on ${PORT}`));
Then in /routes/api/user/user.js you would have something like:
const express = require("express");
const router = express.Router();
router.post("/create", (req, res) => {
try {
// Create user
} catch (error) {
console.log(error);
res.sendStatus(500);
}
});
module.exports = router;
Add and index.js inside /routes/api/user to point at the user file to keep things pretty when importing (otherwise you have to import it like /routes/api/user/user):
const user = require("./user");
module.exports = user;
Importing Single File
Not sure your use case but variables could be a bad naming convention since these values are more like constants than variables. Either way, you create it like this:
const variables = {
varibleOne: "valueOne",
varibleTwo: "valueTwo",
varibleThree: "valueThree",
};
module.exports = variables;
Then wherever you want to import it you can do:
const variables = require("./variables");
and access it like so variables.variableOneand so on.
Importing functions
You can also import different functions, say you need a file called helper.js where these are commonly functions needed all over you app, you could do something like this:
const twoDecimals = (number, decimal = ",") => {
let val = (Math.round(number * 100) / 100).toFixed(2);
return decimal === "." ? val : val.replace(".", decimal);
};
const getRandomInt = (max) => {
return Math.floor(Math.random() * Math.floor(max));
};
module.exports = { twoDecimals, getRandomInt };
Then wherever you needed you can import it by:
const { twoDecimals } = require("helper.js");
Now you have access to your helper functions anywhere.
You should get help from the JavaScript modular system (preferably COMMONJS).
For example, suppose we have two files:
1-module.js 2-app.js
So now let's create this files
module.js
let name = "hello world";
function printSomething(message) {
console.log(message)
}
//here export all function and variable
module.exports.name = name;
module.exports.printSomething = printSomething
ok so Well now it is enough that "require" this file in main file :
main.js
// we
const {name, printSomething} = require("./module.js");
printSomething(name);
for export all variable You need to create an object and specify your variables as a property:
let host = "localhost"
let dbname = "laravel_8"
let username = "root"
let password = "root"
function doSomething() {
console.log("hello");
}
module.exports = {host, dbname, username, password, doSomething}
so in main file :
const variables = require("./module.js")
//host
let host = variables.host
//dbname
let dbname = variables.dbname
//function doSomething
let doSomething = variables.doSomething;
doSomething()
// or directly
variables.doSomething()
In fact, in php we use the "->" symbol to access properties, and in JavaScript we use "."

can not get cascade DDS value for SharedObjectSequence

I have a test like this, but i can not get the 'sharedMap' in 'sharedSeq1' value, i don't know how to get the 'remoteFluidObjectHandle' value.
import {MockContainerRuntimeFactory, MockFluidDataStoreRuntime, MockStorage} from "#fluidframework/test-runtime-utils";
import {SharedObjectSequence, SharedObjectSequenceFactory} from "#fluidframework/sequence";
import * as mocks from "#fluidframework/test-runtime-utils";
import {SharedMap} from "#fluidframework/map";
import {IFluidHandle} from "#fluidframework/core-interfaces";
const mockRuntime: mocks.MockFluidDataStoreRuntime = new mocks.MockFluidDataStoreRuntime();
describe('ShredObjectSequence', function () {
it('should get synchronization data from another shared object', async function () {
const dataStoreRuntime1 = new MockFluidDataStoreRuntime();
const sharedSeq1: SharedObjectSequence<IFluidHandle<SharedMap>> = new SharedObjectSequence(mockRuntime, 'shareObjectSeq1', SharedObjectSequenceFactory.Attributes,)
const containerRuntimeFactory = new MockContainerRuntimeFactory();
dataStoreRuntime1.local = false;
const containerRuntime1 = containerRuntimeFactory.createContainerRuntime(
dataStoreRuntime1,
);
const services1 = {
deltaConnection: containerRuntime1.createDeltaConnection(),
objectStorage: new MockStorage(),
};
sharedSeq1.initializeLocal();
sharedSeq1.connect(services1);
const dataStoreRuntime2 = new MockFluidDataStoreRuntime();
const containerRuntime2 = containerRuntimeFactory.createContainerRuntime(
dataStoreRuntime2,
);
const services2 = {
deltaConnection: containerRuntime2.createDeltaConnection(),
objectStorage: new MockStorage(),
};
const sharedSeq2: SharedObjectSequence<IFluidHandle<SharedMap>> = new SharedObjectSequence(mockRuntime, 'shareObjectSeq2', SharedObjectSequenceFactory.Attributes,)
sharedSeq2.initializeLocal();
sharedSeq2.connect(services2);
// insert a node into sharedSeq2, it will sync to sharedSeq1
sharedSeq2.insert(0, [<IFluidHandle<SharedMap>>new SharedMap('sharedMapId', mockRuntime, SharedMap.getFactory().attributes).handle])
containerRuntimeFactory.processAllMessages();
// next case is passed, it show we got the sharedSeq2 changed
expect(sharedSeq1.getLength()).toBe(1)
const remoteFluidObjectHandle = await sharedSeq1.getRange(0, 1)[0];
// at here, i get error: Cannot read property 'mimeType' of null, it cause by remoteFluidObjectHandle.ts:51:30
const sharedMap = await remoteFluidObjectHandle.get()
expect(sharedMap).not.toBeUndefined()
});
});
run this test will get 'Cannot read property 'mimeType' of null' error, it caused by 'remoteFluidObjectHandle.ts:51:30'
The fluid mocks have very limited and specific behaviors, it looks like you are hitting the limits of them. You'll have better luck with an end-to-end test, see packages\test\end-to-end-tests. These use the same in-memory server as our as the playground on fluidframework dot com. The in-memory server uses the same code as tinylicious, our single process server and routerlicious, our docker based reference implementation.

Assert that the function passed into a stubbed function is the correct function

I'm trying to test my Node module using Mocha.
The module is very small here is an example...
import { sharedFunctionA, sharedFunctionB, commonFunction } from <file>
const functionA = token => _data => sharedFunctionA(token);
const functionB = () => data => sharedFunctionB(data);
exports.doThingA = token => {
commonFunction(functionA(token));
};
exports.doThingB = () => {
commonFunction(functionB());
};
This is only a brief example but it shows what I'm trying to do.
I need to test that doThingA and doThingB pass in the correct function to the commonFunction.
I have stubbed the commonFunction and I can see that it is being called but I can't assert that the function passed in is correct.
TBH... I'm beginning to think of restructuring this entirely to pass in some sort of enum to the commonFunction and running the respective function from there.
In this case you can stub on the sharedFunctionA and sharedFunctionB and then retrieve the argument of your stub on the commonFunction and call it. Then check your other stubs are being called with the desired arguments.
I know it's tedious but it is the only way I can think of with your code.
Quick example:
const assert = require('assert')
const sinon = require('sinon')
const sharedFunctions = require('<fileWithSharedFunctions>')
const commonStub = sinon.stub(sharedFunctions, 'commonFunction')
const sharedBStub = sinon.stub(sharedFunctions, 'sharedFunctionB')
const fileToTest = require('<fileToTest>')
fileToTest.doThingB()
commonStub.getCall(0).args[0]()
assert(sharedBStub.calledOnce)

Is there a way to change the mocked value of a required dependency?

I'm facing a problem I'm not able to resolve on my own, maybe some of you faced the same problem.
Let me show you what I'm trying to do, here is the mock:
let mockConfig = {name: 'dude'};
jest.mock('../../../configManager', () => mockConfig);
configManager is a dependency of the function I'm trying to test.
It works well but I want to change the returning object of configManager in another test so the tested function behaves differently.
Let me show you, here is the function I'm testing:
const config = require('../../../configManager');
module.exports = () => {
if (config.name === 'dude') {
do stuff;
}
if (config.name === 'dudette') {
do something else;
}
So, typically, I want to change the config.name to 'dudette' to be able to test the second part of my function.
Naturally, when I want to do this with an imported function, I just do:
let mockJsonQueryResult = { value: 'stuff' };
jest.mock('json-query', () => jest.fn(() => mockJsonQueryResult));
and then in the test, I directly set another value to mockJsonQueryResult:
mockJsonQueryResult = { value: 'hotterStuff' };
But I don't find any way of doing this with a dependency that returns an object, with a dependency returning a function, no problem.
Is there even any way of doing this?
Thanks in advance!
Edit: this is not the same as how to change jest mock function return value in each test? as #Dor Shinar suggested because his problem is to mock a function, even if it is inside a returning object it is still a function, I just want to change a value inside the returned object.
So, I found a solution I'm not completely satisfied with but it works:
I simply set the original full object and then for my tests, change the value of specific properties by setting them directly before calling the function I want to test.
example:
let mockConfig = { person: { name: 'dude', origin: {country: 'France'} } };
jest.mock('../../../configManager', () => mockConfig);
mockConfig.person = {};
mockConfig.person.name = 'dudette';
You don't need to mock the module at all.
If your module export is just an object with property values then just change the properties as needed.
Here is a simple working example to demonstrate:
configManager.js
module.exports = {
name: 'original'
}
code.js
const config = require('./configManager');
module.exports = () => `name: ${config.name}`;
code.test.js
const config = require('./configManager');
const func = require('./code');
test('func', () => {
expect(func()).toBe('name: original'); // Success!
config.name = 'dude';
expect(func()).toBe('name: dude'); // Success!
config.name = 'dudette';
expect(func()).toBe('name: dudette'); // Success!
})
Details
A module binding can't be directly changed to something else:
const config = require('./configManager');
config = { name: 'mock' }; // <= this doesn't work
...but you can change the properties of an object representing a module binding:
const config = require('./configManager');
config.name = 'mock'; // <= this works!
...and any code using the module will automatically see the changes.

Resources