TypeError when mocking request with jest - node.js

I'm relatively new to node and am having issues trying to mock request using jest.
If my file to be tested has require('request'), and I try to run npm test, I get this error:
FAIL __tests__/sum-test.js (0.291s)
● sum › it adds 1 + 2 to equal 3
- TypeError: The super constructor to `inherits` must have a prototype.
at Object.exports.inherits (util.js:756:11)
at Object.<anonymous> (node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/private-key.js:44:6)
at Object.<anonymous> (node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/utils.js:16:18)
Here's my package.json, if that helps:
{
"name": "jesttest",
"version": "1.0.0",
"scripts": {
"test": "jest"
},
"devDependencies": {
"jest-cli": "^12.0.2"
},
"dependencies": {
"request": "^2.72.0"
}
}
Anyone know why this might be happening?

add jest.unmock('request') in your test file.
Jest will mock a fake require object when you require something in your file.In this situation, request is not the real request.So tell jext not mock request.

Related

TypeError: trying to use aws-elasticsearch-connector

I'm attempting to update a legacy elastic-search node app, using the the package aws-elasticsearch-connector
and for some reason I'm unable to get it to work at all, even the simplest provided example...
I installed the packages, exactly as shown...
> npm install --save aws-elasticsearch-connector #elastic/elasticsearch aws-sdk
This is the sample code...
const { Client } = require('#elastic/elasticsearch')
const AWS = require('aws-sdk')
const createAwsElasticsearchConnector = require('aws-elasticsearch-connector')
// (Optional) load profile credentials from file
AWS.config.update({
profile: 'myawsprofile'
})
const client = new Client({
...createAwsElasticsearchConnector(AWS.config),
node: 'https://my-elasticsearch-cluster.us-east-1.es.amazonaws.com'
})
When I attempt to run it with this...
> node .\index.js
I get this error...
class AmazonConnection extends Connection {
TypeError: Class extends value undefined is not a constructor or null
I have no idea how I'm supposed to fix this, since the error seems to be in the module itself, not my sample code.
Most of the examples of this error that I've seen, suggest that it's related to circular references, but that doesn't seem to be of any help to me.
I'm using node v16.14.0
This is my package.json...
{
"name": "test_es",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"#elastic/elasticsearch": "^8.0.0",
"aws-elasticsearch-connector": "^9.0.3",
"aws-sdk": "^2.1087.0"
}
}
I'm probably doing something wrong, or the package author may be assuming some additional knowledge that I just don't have.
Any suggestions would be greatly appreciated.
It seems version 8 of #elastic/elasticsearch is not compatible with aws-elasticsearch-connector.
Changing to version 7.17.0 seems to resolve this particular error.

Babel and Node - No stack trace on syntax errors

I am converting a project over from using gulp to using nodemon so that I can use ES6 with babel. I'm following a pretty simple procedure to do so, which is well described here. A quick look at my package.json:
{
"main": "index.js",
"scripts": {
"start": "FORCE_COLOR=3 nodemon --exec babel-node index.js"
},
"dependencies": {
"deps": "1.1.1"
},
"devDependencies": {
"#babel/cli": "^7.16.0",
"#babel/core": "^7.16.5",
"#babel/node": "^7.16.5",
"#babel/polyfill": "^7.12.1",
"#babel/preset-env": "^7.16.5",
"nodemon": "^2.0.15"
},
"babel": {
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": "current"
}
}
]
]
}
}
When I run npm start, nodemon runs the app, and reruns on save, but it crashes with a syntax error:
[nodemon] starting `babel-node index.js`
[HPM] Proxy created: /auth -> http://localhost:8081/
/myproject/node_modules/#babel/core/lib/parser/index.js:93
throw err;
^
SyntaxError: Legacy octal literals are not allowed in strict mode. (38:46)
at Parser._raise (/myproject/node_modules/#babel/parser/src/parser/error.js:147:45)
at Parser.raiseWithData (/myproject/node_modules/#babel/parser/src/parser/error.js:142:17)
at Parser.raise (/myproject/node_modules/#babel/parser/src/parser/error.js:91:17)
at Parser.recordStrictModeErrors (/myproject/node_modules/#babel/parser/src/tokenizer/index.js:1444:12)
at Parser.readNumber (/myproject/node_modules/#babel/parser/src/tokenizer/index.js:1239:12)
at Parser.getTokenFromCode (/myproject/node_modules/#babel/parser/src/tokenizer/index.js:951:14)
at Parser.nextToken (/myproject/node_modules/#babel/parser/src/tokenizer/index.js:307:10)
at Parser.next (/myproject/node_modules/#babel/parser/src/tokenizer/index.js:169:10) {
loc: Position { line: 38, column: 46 },
pos: 933,
code: 'BABEL_PARSE_ERROR',
reasonCode: 'StrictOctalLiteral'
}
[nodemon] app crashed - waiting for file changes before starting...
There doesn't seem to be a stack trace to the place in my code where this error is happening. I managed to track it down with some careful understanding of the no octal error, but other errors that come up look very similar, with no stack trace to the place in my own code where the error occurs. How can I debug like that? Is there a way to configure babel to include the origin of the error from my code?
Running babel-node with Node 16.9 seems to fix this.
With Node 12 to 16.8:
SyntaxError: Legacy octal literals are not allowed in strict mode. (1:4)
at Parser._raise (/tmp/babel-test-3/node_modules/#babel/parser/lib/index.js:569:17)
With Node 16.9+:
SyntaxError: /tmp/babel-test-3/index2.js: Legacy octal literals are not allowed in strict mode. (1:4)
> 1 | a = 01;
| ^
2 |
at Parser._raise (/tmp/babel-test-3/node_modules/#babel/parser/lib/index.js:569:17)
No other changes were required.
A bug report has been filed.
It could potentially be that there is something wrong with the package itself. But babel is a properly and well maintained project so it could be something on your end
The error here is that leading zeros aren't allowed. Try and remove any instance of hard-coded leading zeros and then use +number or parseInt on any numbers which the values you won't know, such as from an API, reading from a database, or receiving user input.

node throw error when use async/await syntax.but it works well with import/export syntax

nodemon throw the error when use async/await syntax:
**/node_modules/#babel/runtime/helpers/esm/asyncToGenerator.js:17
export default function _asyncToGenerator(fn) {
^^^^^^
SyntaxError: Unexpected token export
but it works well with import/export syntax.
package.json
{
"scripts": {
"dev": "nodemon --exec babel-node server/index.js",
}
"dependencies": {
"#babel/polyfill": "^7.2.5",
},
"devDependencies": {
"#babel/cli": "^7.2.3",
"#babel/core": "^7.2.2",
"#babel/node": "^7.2.2",
"#babel/preset-env": "^7.2.3",
}
}
.babelrc
{
"presets": [
"#babel/preset-env"
]
}
asyncToGenerator.js
function asyncGeneratorStep(...) { ... }
export default function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
But I think it probably goes wrong because of my babel setting.
BTW, when I use typeof, it throws the same error
**/node_modules/#babel/runtime/helpers/esm/typeof.js:3
export default function _typeof(obj) {
^^^^^^
SyntaxError: Unexpected token export
update 6/12, 2020:
structure:
src (vue app)
server (express app)
|---- src
|---- babel.config.js
|---- index.js
package.json
babel.config.js
In this project, I have two babel config, one is for the vue's app, and another is for the express. What I want is running these apps at the project's root path.
And in the beginning, my script about running express is
nodemon --exec babel-node server/index.js
It can run express, but it gets the wrong babel config(project/babel.config.js)
And the solution is just to point out the specific path which babel confg you want to use(project/server/babel.config.js). So the correct script to run the express is
nodemon --exec babel-node --config-file ./server/babel.config.js server/index.js",
answering your comment:
nodemon doesn't know about babelrc (and it shouldn't). And babel (AFAIK) doesn't allow you to select the babelrc file that you want to use.
I think that you should merge your babelrc files and set the env flag when running babel-node. Like this: babeljs.io/docs/en/6.26.3/babelrc#env-option
Another option would be to make a script that renames the babelrc file each time the app is reloaded, or something like that (I don't understand why you need 2 .babelrc files)
In an answer no longer visible (probably deleted by a moderator) I read that there are more .babelrc files in the project.
From babel docs it seems that the .babelrc needs to be in the same directory of the subpackage. I suggest you to read that doc, probably you can find the solution that better fits your requirements.
Sorry for the vague answer, but due to the lack of details in your question (server/index.js file content, directories structure, etc.) I can't do better.

Zeit/pkg: Cannot find module 'config'

I've distilled this issue down to a simple test. I'm using the node "config" module to define configuration values for my app. Pkg doesn't complain on build, but barfs at runtime with the following message. Am I missing something?
jim-macbookpro:~/development/node/pkgtest$ ./pkgtest-macos
pkg/prelude/bootstrap.js:1172
throw error;
^
Error: Cannot find module 'config'
1) If you want to compile the package/file into executable, please pay attention to compilation warnings and specify a literal in 'require' call. 2) If you don't want to compile the package/file into executable and want to 'require' it from filesystem (likely plugin), specify an absolute path in 'require' call using process.cwd() or process.execPath.
at Function.Module._resolveFilename (module.js:540:15)
at Function.Module._resolveFilename (pkg/prelude/bootstrap.js:1269:46)
at Function.Module._load (module.js:470:25)
at Module.require (module.js:583:17)
at Module.require (pkg/prelude/bootstrap.js:1153:31)
at require (internal/module.js:11:18)
at Object.<anonymous> (/snapshot/pkgtest/index.js:1:78)
at Module._compile (pkg/prelude/bootstrap.js:1243:22)
at Object.Module._extensions..js (module.js:650:10)
at Module.load (module.js:558:32)
index.js is simple:
const config = require('config');
console.log('yo:', config.message);
and I have a default.json in the local 'config' directory:
{
"message": "whodapunk?"
}
My package.json, for what it's worth:
{
"name": "pkgtest",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"config": "^1.30.0"
},
"bin": "index.js"
}
I had the same issue and it was because my config file was added to .gitignore -- as soon as I removed it from there it worked like a charm!
I just had the same issue. However not a really beautiful solution I managed to find a way to work around it.
When calling pkg I do not set e NODE_ENV. Then in my entry point I check if a NODE_ENV is set. If not I define the variables I need there.
let port = null;
let db = null;
let name = null;
if (process.env.NODE_ENV) {
const config = require('config');
port = config.get('port');
db = config.get('database');
name = config.get('name');
} else {
port = 3000;
db = 'mongodb://localhost:27017/production';
name = 'Server Production';
}
I tried linking directly to the config module but after that it started complaining that it could not find and files in my config folder. This worked for me as a work around.

Register Node Module Manually

Question:
I have a project in TypeScript that uses several APIs I don't have access to on my computer (they exist on the web). The code will compile fine locally since I have all the APIs in foo.d.ts files, and so the system knows they exist somewhere.
However, I want to unit test parts of the code with a NodeJS app. I can import the code into node just fine, but whenever I reach code that imports a module from a definition file, I get the following error:
Error: Cannot find module 'messages'
at Function.Module._resolveFilename (module.js:527:15)
at Function.Module._load (module.js:476:23)
at Module.require (module.js:568:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (~/dev/repos/sample_typescript_fail/App.js:3:18)
at Module._compile (module.js:624:30)
at Object.Module._extensions..js (module.js:635:10)
at Module.load (module.js:545:32)
at tryModuleLoad (module.js:508:12)
at Function.Module._load (module.js:500:3)
...
This makes sense, since that code is just defined locally, and does not exist.
Can I manually register modules to NodeJS, like
Registry.register('messages', () => {...});
so that I can compile and test with polyfills?
Here's an example app
package.json
{
"name": "sample_typescript_declare_issue",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"scripts": {
"start": "ts-node index.ts"
},
"author": "",
"license": "MIT"
}
index.ts
import {App} from "./App";
console.log("Starting program");
// How do I fake "import {MessageSender} from "messages";"
// here so that I can run this node app as a test?
let app: App = new App();
console.log("Ending program");
App.ts
import {MessageSender} from "messages";
export class App {
constructor() {
let messageSender: MessageSender = new MessageSender();
messageSender.sendMessage("foo!");
}
}
node_modules/#types/messages/index.d.ts
export = Messages;
export as namespace Messages;
declare module Messages {
class MessageSender {
constructor();
sendMessage(message: any): void;
}
}
Running Example App
Running with npm start gives the error message above.
Running tsc *.tsc compiles just fine.
Other things I've tried
Updating package.json to include a bin:
{
"name": "sample_typescript_declare_issue",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"scripts": {
"start": "ts-node index.ts"
},
"author": "",
"license": "MIT",
"bin": {
"messages": "./polyfills/messages/index.ts"
}
}
As you mentioned, compiling works fine - this is just a question of availability of .d.ts files.
What you want to do is alter module import at runtime, in other words alter the behaviour of the nodejs require function since
import {MessageSender} from "messages";
will be transpiled in javascript (ES6) to something like
const messages_1 = require("messages");
...
messages_1.MessageSender
To modify that behaviour, the first thing that springs to mind is to use the deprecated - but still available - require.extensions object.
When running locally you must first inject something like
require.extensions['.js'] = (module, filename) => {
if (filename === 'messages') {
// then load mock module/polyfill using the passed module object
// see (https://nodejs.org/api/modules.html#modules_the_module_object)
}
};
The doc says there are better alternatives but fails to clearly mention any.
Another possibility is to look at projects like sandboxed-module which should help (I have not tested it)

Resources