Importing ethers via Hardhat fails despite official testing documentation - javascript

According to the official testing documentation for Hardhat, ethers should be available implicitly within the global scope; however, it can optionally be required explicitly, like so:
const { ethers } = require("hardhat");
This fails for my local project.
My package manifest seems to include the correct dependencies:
{
"dependencies": {
"#nomiclabs/hardhat-ethers": "^2.0.1",
"#nomiclabs/hardhat-waffle": "^2.0.1",
"#openzeppelin/contracts": "https://github.com/OpenZeppelin/openzeppelin-contracts#v4.0.0-beta.0",
"chai": "^4.3.1",
"hardhat": "^2.0.11"
}
}
My unit tests file seems to match the worked example in the Hardhat documentation also:
const { ethers } = require("hardhat");
const { expect } = require("chai");
describe("Distributor.sol", function() {
it("Distribution should fail for non-owners", async function() {
const DistributorFactory = await ethers.getContractFactory("Distributor");
const Distributor = await Distributor.deploy();
Distributor.distribute([], []);
expect(await hardhatToken.totalSupply()).to.be.revertedWith("foobar");
});
});
Despite this, running the tests fails with:
$ yarn hardhat test
yarn run v1.22.5
$ /home/bob/dev/misc/token-distributor/node_modules/.bin/hardhat test
Distributor.sol
undefined
1) Distribution should fail for non-owners
0 passing (9ms)
1 failing
1) Distributor.sol
Distribution should fail for non-owners:
TypeError: Cannot read property 'getContractFactory' of undefined
at Context.<anonymous> (test/Distributor.js:8:49)
at processImmediate (internal/timers.js:461:21)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
How do I fix this?

Two things:
you need to install ethers separately too, as given in the instructions for hardhat-ethers, e.g.
npm install --save-dev #nomiclabs/hardhat-ethers 'ethers#^5.0.0'
Every Hardhat plugin needs to be registered in the Hardhat config file (hardhat.config.js):
require("#nomiclabs/hardhat-ethers");
There is no need to remove the explicit import in your test file, however, Hardhat docs recommend following this style:
const hre = require("hardhat");
const { ethers } = hre;

Add the require in your hardhat.config.js
require("#nomiclabs/hardhat-waffle");
And remove this line from your test file:
const { ethers } = require("hardhat");
Then, you can use ethers in your tests. Hardhat looks in the config first before running tests. If you have required a package that includes ethers you can use it in the global scope.

It still shows error, reading ethers undefined, I started the project all again with yarn hardhat and chose the first option "Create Simple Project" and it works perfectly.

Related

Adding opentelemetry tracing to Node.js app breaks `require("fs").realpathSync.native`

Using the following tracing enabling script from OpenTelemetry docs:
const opentelemetry = require("#opentelemetry/sdk-node");
const { getNodeAutoInstrumentations } = require("#opentelemetry/auto-instrumentations-node");
const { diag, DiagConsoleLogger, DiagLogLevel } = require('#opentelemetry/api');
// For troubleshooting, set the log level to DiagLogLevel.DEBUG
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO);
const sdk = new opentelemetry.NodeSDK({
traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(),
instrumentations: [getNodeAutoInstrumentations()]
});
sdk.start()
running my Next.js server as I thought is required, I get an error:
$ node --require './tracing/opentelemetry.js' ./node_modules/next/dist/bin/next start -p 3000
No modules instrumentation has been defined, nothing will be patched
#opentelemetry/instrumentation-grpc Module #grpc/grpc-js has been loaded before #opentelemetry/instrumentation-grpc so it might not work, please initialize it before requiring #grpc/grpc-js
Exporter "otlp" requested through environment variable is unavailable.
/mnt/vol/.local/share/pnpm/global/5/.pnpm/next#12.1.5_zpnidt7m3osuk7shl3s4oenomq/node_modules/next/dist/lib/get-project-dir.js:40
const realDir = _fs.default.realpathSync.native(resolvedDir);
^
TypeError: _fs.default.realpathSync.native is not a function
at Object.getProjectDir (/mnt/vol/.local/share/pnpm/global/5/.pnpm/next#12.1.5_zpnidt7m3osuk7shl3s4oenomq/node_modules/next/dist/lib/get-project-dir.js:40:50)
at nextStart (/mnt/vol/.local/share/pnpm/global/5/.pnpm/next#12.1.5_zpnidt7m3osuk7shl3s4oenomq/node_modules/next/dist/cli/next-start.js:80:37)
at /mnt/vol/.local/share/pnpm/global/5/.pnpm/next#12.1.5_zpnidt7m3osuk7shl3s4oenomq/node_modules/next/dist/bin/next:141:34
at processTicksAndRejections (node:internal/process/task_queues:96:5)
Node.js v17.8.0
Now this can be simplified to a minimal reproduction as follows. This has the fs.realpathSync.native function:
$ node -e 'console.log(require("fs").realpathSync)'
[Function: realpathSync] { native: [Function (anonymous)] }
This doesn't have fs.realpathSync.native:
$ node --require ./tracing/opentelemetry.js -e 'console.log(require("fs").realpathSync)'
No modules instrumentation has been defined, nothing will be patched
#opentelemetry/instrumentation-grpc Module #grpc/grpc-js has been loaded before #opentelemetry/instrumentation-grpc so it might not work, please initialize it before requiring #grpc/grpc-js
[Function (anonymous)]
Exporter "otlp" requested through environment variable is unavailable.
My Node's --require is working correctly (noop.js is an empty file):
$ node --require ./tracing/noop.js -e 'console.log(require("fs").realpathSync)'
[Function: realpathSync] { native: [Function (anonymous)] }
Why would the OpenTelemetry setup script break the fs module?
$ node --version
v17.8.0
//package.json dependencies
"#opentelemetry/api": "^1.3.0",
"#opentelemetry/auto-instrumentations-node": "^0.35.0",
"#opentelemetry/sdk-node": "^0.34.0",
$ uname -a
Linux code-server 5.15.0-1025-oracle #31~20.04.2-Ubuntu SMP Tue Nov 29 13:01:56 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
Does my ARM machine have something to do with it?
I can reproduce the same on x86_64 on https://replit.com/#JakubKoralewski/opentelemetry-repro with the same behavior.
The reason this error occurs is due to a bug in #opentelemetry/instrumentation-fs introduced as a new dependency to #opentelemetry/auto-instrumentations-node in PR #981 which got released with version 0.34.0. The issue was reported but at the time of writing is still open. However, as also already linked above a PR to address the issue is being reviewed.
Fow now, I see three ways to address the problem:
As suggested in a comment above downgrade #opentelemetry/auto-instrumentations-node to next lower version 0.33.1.
Disable the file system instrumentation when configuring the node instrumentation. For that simply replace getNodeAutoInstrumentations() with getNodeAutoInstrumentations({ '#opentelemetry/instrumentation-fs': { enabled: false } }) in your code. Given that your project is in Next.js and you likely have little file system activity aside from maybe public files this is likely the best option for now.
Remove #opentelemetry/auto-instrumentations-node altogether and simply instrument the libraries you actually use. Using the auto instrumentation for Node.js pulls in a lot of transitive dependencies. Say you have a Next.js app, connect to a Postgres database and use winston for logging your instrumentation setup could look something like this:
const sdk = new opentelemetry.NodeSDK({
traceExporter: new opentelemetry.tracing.ConsoleSpanExporter(),
instrumentations: [
// new FsInstrumentation(), TODO: re-enable once bug is fixed
new HttpInstrumentation(),
new PgInstrumentation(),
new WinstonInstrumentation(),
]
});

TypeError: Cannot read properties of undefined (reading 'getContractFactory') when testing contract

First question so bare with me if it is not very clear, but I'll try my best.
I am currently running through a youtube video to test my contract with hardhat, ethers, and waffle (https://www.youtube.com/watch?v=oTpmNEYV8iQ&list=PLw-9a9yL-pt3sEhicr6gmuOQdcmWXhCx4&index=6).
Here is the contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyContract is ERC721 {
constructor(string memory name, string memory symbol)
ERC721(name, symbol) {
}
}
And here is test.js:
const { expect } = require('chai');
describe("MyContract", function() {
it("should return correct name", async function() {
const MyContract = hre.ethers.getContractFactory("MyContract");
const myContractDeployed = await MyContract.deploy("MyContractName", "MCN");
await myContractDeployed.deployed();
expect(await myContractDeployed.name()).to.equal("MyContractName");
});
});
when I run "npx hardhat test" in the terminal it returns:
MyContract
1) should return correct name
0 passing (7ms)
1 failing
1) MyContract
should return correct name:
TypeError: Cannot read properties of undefined (reading 'getContractFactory')
at Context.<anonymous> (test\test.js:7:35)
at processImmediate (node:internal/timers:464:21)
My code matches the one from the video, and I am having a tough time understanding why I am getting a TypeError here. Any guidance is much appreciated!
EDIT:
I somehow fixed it, I dont understand how exactly it fixed it but it did. Instead of just installing
npm install #nomiclabs/hardhat-waffle ethereum-waffle chai #nomiclabs/hardhat-ethers ethers
I installed
npm install --save-dev #nomiclabs/hardhat-waffle ethereum-waffle chai #nomiclabs/hardhat-ethers ethers
Then the terminal printed
npm WARN idealTree Removing dependencies.#nomiclabs/hardhat-waffle in favor of devDependencies.#nomiclabs/hardhat-waffle
npm WARN idealTree Removing dependencies.ethereum-waffle in favor of devDependencies.ethereum-waffle
npm WARN idealTree Removing dependencies.#nomiclabs/hardhat-ethers in favor of devDependencies.#nomiclabs/hardhat-ethers
npm WARN idealTree Removing dependencies.ethers in favor of devDependencies.ethers
then I removed the hre in front of ethers.getContractFactory("MyContract") and it worked! If anyone would like to explain why this might have fixed it I'd be happy to read it, otherwise I am moving on.
Add the following code snippet at the top of your hardhat.config.js file
require("#nomiclabs/hardhat-waffle");
Sometimes it is because any of these dependencies below missing. Especially if you are using dotenv file and forgetting to import it. So, put these import statements on your hardhat.config or truffle.config file:
require("#nomicfoundation/hardhat-toolbox");
require("#nomiclabs/hardhat-ethers");
require("dotenv").config();
You needed to import hre in the test code.
const hre = require("hardhat");

hardhat run with parameters

I need to run a particular ts script using hardhat from the command line but I need to specify parameters... Similar to this:
npx hardhat run --network rinkeby scripts/task-executor.ts param1 param2
Where the --network rinkeby is the parameter for the hardhat run
And param1 and param2 are parameters for the task-executor.ts script.
I couldn't find any post regarding this issue and I cannot make it work.
I also tried defining a hardhat task and added those parameters but if I try to execute it I get:
Error HH9: Error while loading Hardhat's configuration.
You probably tried to import the "hardhat" module from your config or a file imported from it.
This is not possible, as Hardhat can't be initialized while its config is being defined.
Because I need to import hre or ethers from hardhat in that particular task.
Does anybody know how to accomplish what i need ??
Thanks a lot!!
According to Hardhat:
Hardhat scripts are useful for simple things that don't take user arguments, and for integrating with external tools that aren't well suited for the Hardhat CLI, like a Node.js debugger.
For scripts that require parameters, you should use Hardhat Tasks.
You can code the task in a different file than hardhat.config.ts. Here is an example task using positional parameters in the file sampleTask.ts:
import { task } from "hardhat/config";
task("sampleTask", "A sample task with params")
.addPositionalParam("param1")
.addPositionalParam("param2")
.setAction(async (taskArgs) => {
console.log(taskArgs);
});
Remember to import it inside hardhat.config.ts:
import "./tasks/sampleTask";
Then run it with:
npx hardhat sampleTask hello world
And it should print:
{ param1: 'hello', param2: 'world' }
You can read more about named, positional and optional parameters on tasks here.
If you need to use hre or ethers, you can get hre from the second parameter of the setAction function:
task("sampleTask", "A sample task with params")
.addPositionalParam("param1")
.addPositionalParam("param2")
.setAction(async (taskArgs, hre) => {
const ethers = hre.ethers;
});
It could be useful to check the diferences between a script and a task and how to choose: Hardhat has This on documentation.
Usually it works like this:
const hre = require('hardhat');
const { ethers } = hre;

Renaming file by using Node Package Version [duplicate]

Is there a way to get the version set in package.json in a nodejs app? I would want something like this
var port = process.env.PORT || 3000
app.listen port
console.log "Express server listening on port %d in %s mode %s", app.address().port, app.settings.env, app.VERSION
I found that the following code fragment worked best for me. Since it uses require to load the package.json, it works regardless of the current working directory.
var pjson = require('./package.json');
console.log(pjson.version);
A warning, courtesy of #Pathogen:
Doing this with Browserify has security implications.
Be careful not to expose your package.json to the client, as it means that all your dependency version numbers, build and test commands and more are sent to the client.
If you're building server and client in the same project, you expose your server-side version numbers too.
Such specific data can be used by an attacker to better fit the attack on your server.
If your application is launched with npm start, you can simply use:
process.env.npm_package_version
See package.json vars for more details.
Using ES6 modules you can do the following:
import {version} from './package.json';
Or in plain old shell:
$ node -e "console.log(require('./package.json').version);"
This can be shortened to
$ node -p "require('./package.json').version"
There are two ways of retrieving the version:
Requiring package.json and getting the version:
const { version } = require('./package.json');
Using the environment variables:
const version = process.env.npm_package_version;
Please don't use JSON.parse, fs.readFile, fs.readFileSync and don't use another npm modules it's not necessary for this question.
For those who look for a safe client-side solution that also works on server-side, there is genversion. It is a command-line tool that reads the version from the nearest package.json and generates an importable CommonJS module file that exports the version. Disclaimer: I'm a maintainer.
$ genversion lib/version.js
I acknowledge the client-side safety was not OP's primary intention, but as discussed in answers by Mark Wallace and aug, it is highly relevant and also the reason I found this Q&A.
Here is how to read the version out of package.json:
fs = require('fs')
json = JSON.parse(fs.readFileSync('package.json', 'utf8'))
version = json.version
EDIT: Wow, this answer was originally from 2012! There are several better answers now. Probably the cleanest is:
const { version } = require('./package.json');
There is another way of fetching certain information from your package.json file namely using pkginfo module.
Usage of this module is very simple. You can get all package variables using:
require('pkginfo')(module);
Or only certain details (version in this case)
require('pkginfo')(module, 'version');
And your package variables will be set to module.exports (so version number will be accessible via module.exports.version).
You could use the following code snippet:
require('pkginfo')(module, 'version');
console.log "Express server listening on port %d in %s mode %s", app.address().port, app.settings.env, module.exports.version
This module has very nice feature - it can be used in any file in your project (e.g. in subfolders) and it will automatically fetch information from your package.json. So you do not have to worry where you package.json is.
I hope that will help.
NPM one liner:
From npm v7.20.0:
npm pkg get version
Prior to npm v7.20.0:
npm -s run env echo '$npm_package_version'
Note the output is slightly different between these two methods: the former outputs the version number surrounded by quotes (i.e. "1.0.0"), the latter without (i.e. 1.0.0).
One solution to remove the quotes in Unix is using xargs
npm pkg get version | xargs echo
Option 1
Best practice is to version from package.json using npm environment variables.
process.env.npm_package_version
more information on: https://docs.npmjs.com/using-npm/config.html
This will work only when you start your service using NPM command.
Quick Info: you can read any values in pacakge.json using process.env.npm_package_[keyname]
Option 2
Setting version in environment variable using https://www.npmjs.com/package/dotenv as .env file and reading it as process.env.version
Just adding an answer because I came to this question to see the best way to include the version from package.json in my web application.
I know this question is targetted for Node.js however, if you are using Webpack to bundle your app just a reminder the recommended way is to use the DefinePlugin to declare a global version in the config and reference that. So you could do in your webpack.config.json
const pkg = require('../../package.json');
...
plugins : [
new webpack.DefinePlugin({
AppVersion: JSON.stringify(pkg.version),
...
And then AppVersion is now a global that is available for you to use. Also make sure in your .eslintrc you ignore this via the globals prop
If you are looking for module (package.json: "type": "module") (ES6 import) support, e.g. coming from refactoring commonJS, you should (at the time of writing) do either:
import { readFile } from 'fs/promises';
const pkg = JSON.parse(await readFile(new URL('./package.json', import.meta.url)));
console.log(pkg.version)
or, run the node process with node --experimental-json-modules index.js to do:
import pkg from './package.json'
console.log(pkg.version)
You will however get a warning, until json modules will become generally available.
If you get Syntax or (top level) async errors, you are likely in a an older node version. Update to at least node#14.
You can use ES6 to import package.json to retrieve version number and output the version on console.
import {name as app_name, version as app_version} from './path/to/package.json';
console.log(`App ---- ${app_name}\nVersion ---- ${app_version}`);
A safe option is to add an npm script that generates a separate version file:
"scripts": {
"build": "yarn version:output && blitz build",
"version:output": "echo 'export const Version = { version: \"'$npm_package_version.$(date +%s)'\" }' > version.js"
}
This outputs version.js with the contents:
export const Version = { version: "1.0.1.1622225484" }
To determine the package version in node code, you can use the following:
const version = require('./package.json').version; for < ES6 versions
import {version} from './package.json'; for ES6 version
const version = process.env.npm_package_version;
if application has been started using npm start, all npm_* environment variables become available.
You can use following npm packages as well - root-require, pkginfo, project-version.
we can read the version or other keys from package.json in two ways
1- using require and import the key required e.g:
const version = require('./package.json')
2 - using package_vars as mentioned in doc
process.env.npm_package_version
You can use the project-version package.
$ npm install --save project-version
Then
const version = require('project-version');
console.log(version);
//=> '1.0.0'
It uses process.env.npm_package_version but fallback on the version written in the package.json in case the env var is missing for some reason.
Why don't use the require resolve...
const packageJson = path.dirname(require.resolve('package-name')) + '/package.json';
const { version } = require(packageJson);
console.log('version', version)
With this approach work for all sub paths :)
In case you want to get version of the target package.
import { version } from 'TARGET_PACKAGE/package.json';
Example:
import { version } from 'react/package.json';
I know this isn't the intent of the OP, but I just had to do this, so hope it helps the next person.
If you're using docker-compose for your CI/CD process, you can get it this way!
version:
image: node:7-alpine
volumes:
- .:/usr/src/service/
working_dir: /usr/src/service/
command: ash -c "node -p \"require('./package.json').version.replace('\n', '')\""
for the image, you can use any node image. I use alpine because it is the smallest.
The leanest way I found:
const { version } = JSON.parse(fs.readFileSync('./package.json'))
I've actually been through most of the solutions here and they either did not work on both Windows and Linux/OSX, or didn't work at all, or relied on Unix shell tools like grep/awk/sed.
The accepted answer works technically, but it sucks your whole package.json into your build and that's a Bad Thing that only the desperate should use temporarily to get unblocked, and in general should be avoided, at least for production code. The alternative is to use that method only to write the version to a single constant that can be used instead of the whole file.
So for anyone else looking for a cross-platform solution (not reliant on Unix shell commands) and local (without external dependencies):
Since it can be assumed that Node.js is installed, and it's already cross-platform for this, I just created a make_version.js file with:
const PACKAGE_VERSION = require("./package.json").version;
console.log(`export const PACKAGE_VERSION = "${PACKAGE_VERSION}";`);
console.error("package.json version:", PACKAGE_VERSION);
and added a version command to package.json:
scripts: {
"version": "node make_version.js > src/version.js",
and then added:
"prebuild": "npm run version",
"prestart": "npm run version",
and it creates a new src/versions.js on every start or build. Of course this can be easily tuned in the version script to be a different location, or in the make_version.js file to output different syntax and constant name, etc.
I do this with findup-sync:
var findup = require('findup-sync');
var packagejson = require(findup('package.json'));
console.log(packagejson.version); // => '0.0.1'
I am using gitlab ci and want to automatically use the different versions to tag my docker images and push them. Now their default docker image does not include node so my version to do this in shell only is this
scripts/getCurrentVersion.sh
BASEDIR=$(dirname $0)
cat $BASEDIR/../package.json | grep '"version"' | head -n 1 | awk '{print $2}' | sed 's/"//g; s/,//g'
Now what this does is
Print your package json
Search for the lines with "version"
Take only the first result
Replace " and ,
Please not that i have my scripts in a subfolder with the according name in my repository. So if you don't change $BASEDIR/../package.json to $BASEDIR/package.json
Or if you want to be able to get major, minor and patch version I use this
scripts/getCurrentVersion.sh
VERSION_TYPE=$1
BASEDIR=$(dirname $0)
VERSION=$(cat $BASEDIR/../package.json | grep '"version"' | head -n 1 | awk '{print $2}' | sed 's/"//g; s/,//g')
if [ $VERSION_TYPE = "major" ]; then
echo $(echo $VERSION | awk -F "." '{print $1}' )
elif [ $VERSION_TYPE = "minor" ]; then
echo $(echo $VERSION | awk -F "." '{print $1"."$2}' )
else
echo $VERSION
fi
this way if your version was 1.2.3. Your output would look like this
$ > sh ./getCurrentVersion.sh major
1
$> sh ./getCurrentVersion.sh minor
1.2
$> sh ./getCurrentVersion.sh
1.2.3
Now the only thing you will have to make sure is that your package version will be the first time in package.json that key is used otherwise you'll end up with the wrong version
I'm using create-react-app and I don't have process.env.npm_package_version available when executing my React-app.
I did not want to reference package.json in my client-code (because of exposing dangerous info to client, like package-versions), neither I wanted to install an another dependency (genversion).
I found out that I can reference version within package.json, by using $npm_package_version in my package.json:
"scripts": {
"my_build_script": "REACT_APP_VERSION=$npm_package_version react-scripts start"
}
Now the version is always following the one in package.json.
I made a useful code to get the parent module's package.json
function loadParentPackageJson() {
if (!module.parent || !module.parent.filename) return null
let dir = path.dirname(module.parent.filename)
let maxDepth = 5
let packageJson = null
while (maxDepth > 0) {
const packageJsonPath = `${dir}/package.json`
const exists = existsSync(packageJsonPath)
if (exists) {
packageJson = require(packageJsonPath)
break
}
dir = path.resolve(dir, '../')
maxDepth--
}
return packageJson
}
If using rollup, the rollup-plugin-replace plugin can be used to add the version without exposing package.json to the client.
// rollup.config.js
import pkg from './package.json';
import { terser } from "rollup-plugin-terser";
import resolve from 'rollup-plugin-node-resolve';
import commonJS from 'rollup-plugin-commonjs'
import replace from 'rollup-plugin-replace';
export default {
plugins: [
replace({
exclude: 'node_modules/**',
'MY_PACKAGE_JSON_VERSION': pkg.version, // will replace 'MY_PACKAGE_JSON_VERSION' with package.json version throughout source code
}),
]
};
Then, in the source code, anywhere where you want to have the package.json version, you would use the string 'MY_PACKAGE_JSON_VERSION'.
// src/index.js
export const packageVersion = 'MY_PACKAGE_JSON_VERSION' // replaced with actual version number in rollup.config.js
const { version } = require("./package.json");
console.log(version);
const v = require("./package.json").version;
console.log(v);
Import your package.json file into your server.js or app.js and then access package.json properties into server file.
var package = require('./package.json');
package variable contains all the data in package.json.
Used to version web-components like this:
const { version } = require('../package.json')
class Widget extends HTMLElement {
constructor() {
super()
this.attachShadow({ mode: 'open' })
}
public connectedCallback(): void {
this.renderWidget()
}
public renderWidget = (): void => {
this.shadowRoot?.appendChild(this.setPageTemplate())
this.setAttribute('version', version)
}
}

"fetch is not found globally and no fetcher passed" when using spacejam in meteor

I'm writing unit tests to check my api. Before I merged my git test branch with my dev branch everything was fine, but then I started to get this error:
App running at: http://localhost:4096/
spacejam: meteor is ready
spacejam: spawning phantomjs
phantomjs: Running tests at http://localhost:4096/local using test-in-console
phantomjs: Error: fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/unfetch.
For example:
import fetch from 'unfetch';
import { createHttpLink } from 'apollo-link-http';
const link = createHttpLink({ uri: '/graphql', fetch: fetch });
Here's a part of my api.test.js file:
describe('GraphQL API for users', () => {
before(() => {
StubCollections.add([Meteor.users]);
StubCollections.stub();
});
after(() => {
StubCollections.restore();
});
it('should do the work', () => {
const x = 'hello';
expect(x).to.be.a('string');
});
});
The funniest thing is that I don't even have graphql in my tests (although, I use it in my meteor package)
Unfortunately, I didn't to find enough information (apart from apollo-link-http docs that has examples, but still puzzles me). I did try to use that example, but it didn't help and I still get the same error
I got the same error importing a npm module doing graphql queries into my React application. The app was compiling but tests were failing since window.fetch is not available in the Node.js runtime.
I solved the problem by installing node-fetch https://www.npmjs.com/package/node-fetch and adding the following declarations to jest.config.js:
const fetch = require('node-fetch')
global.fetch = fetch
global.window = global
global.Headers = fetch.Headers
global.Request = fetch.Request
global.Response = fetch.Response
global.location = { hostname: '' }
Doing so we instruct Jest on how to handle window.fetch when it executes frontend code in the Node.js runtime.
If you're using nodejs do the following:
Install node-fetch
npm install --save node-fetch
Add the line below to index.js:
global.fetch = require('node-fetch');
The problem is this: fetch is defined when you are in the browser, and is available as fetch, or even window.fetch
In the server it is not defined, and either needs to be imported explicity, or a polyfill like https://www.npmjs.com/package/unfetch (as suggested in the error message) needs to be imported by your test code to make the problem go away.

Categories