I'm using Jest to test my api calls file, when I run a simple test I've got an error Cannot find module 'config' from 'api.service.js' which is an import at the top of my api.service.js file:
//api.service.js
import config from "config"; //get data from my webpack.config.js
export const apiService = {getmyData};
function getmyData() {
let queryString = `${config.API}/api/datacall`;
return new Promise(
(resolve, reject) => {
client.get(`${config.API}/api/datacall`).then(result => {
return resolve(result );
});
},
error => {
return reject(error);
}
);
}
Test File in the same folder as the above
//api.spec.js
import getmyDatafrom "./api.service";
const domain = "http://fakeapi.com";
const mockedConsolelog = jest.spyOn(global.console, "log");
const mockedConsoleerror = jest.spyOn(global.console, "error");
Why can't my test file get to my config like the api.service.js?
You probably have to do the import with a relative path.
import config from "./config";
Otherwise, it tries to import something from an npm module called config.
Related
I have defined a function service in one of the file
import Category from '../models/Category.js';
export const AllCategories = () => {
console.log('hit');
const cursor = Category.find({});
console.log(cursor);
return cursor
}
export default {AllCategories}
I am importing this in the controller file
import express from 'express';
import categoryService from '../services/categories.js'
const router = express.Router();
export const getCategories = async(req,res) => {
try {
const categoriesInfo = categoryService.AllCategories
res.status(200).json(categoriesInfo)
} catch (error) {
res.status(404).json({ message: error.message });
}
}
export default router;
But the issue is that AllCategories is not getting run, what is wrong here
I also tried adding async/await
import Category from '../models/Category.js';
export const AllCategories = async () => {
try {
console.log("hit");
const cursor = await Category.find({});
console.log(cursor);
return cursor
} catch (error) {
return error
}
}
export default {AllCategories}
But still no luck
You're not calling the function, this saves it in the variable categoriesInfo:
const categoriesInfo = categoryService.AllCategories
To get its return value:
const categoriesInfo = await categoryService.AllCategories();
Note: I think you need to make it async if you're doing a db transaction so keep the second version and test it.
You can't use the ES module or ESM syntax by default in node.js. You either have to use CommonJS syntax or you have to do 1 of the following.
Change the file extension from .js to .mjs
Add to the nearest package.json file a field called type with a value of module
I am trying to write unit tests of a class which utilizes sqlite3, using TypeScript.
The class itself can correctly utilize sqlite3, but when I try to test the functions which use sqlite3, I get the following error message:
Test suite failed to run
package.json does not exist at C:\...\node_modules\sqlite3\package.json
When I click that link, however, it opens up the package.json file. So it does, actually, exist.
A simplified version of the class under test is as follows:
import sqlite3 from "sqlite3";
import path from "path";
import fs from "fs";
export class DataManager {
database_path: string;
gamertags: { [key: string]: any };
api: object;
constructor() {
//Prepare database
this.database_path = path.join(__dirname, "..", "data", "DBName.db");
}
public mainloop = async () => {
//Setup database
this.setup_db(this.database_path);
};
setup_db = async (db_path: string) => {
//Create data directory if it doesn't exist
if (!fs.existsSync(path.join(__dirname, "..", "data"))) {
fs.mkdirSync(path.join(__dirname, "..", "data"));
}
//Get read/write connection to database
const db = new sqlite3.Database(db_path);
//Serialize context to make sure tables are created in order
db.serialize(() => {
//Create table_1
db.run(`sql_query...`);
//Create table_2
db.run(`sql_query...`);
});
};
}
And my unit tests:
import { DataManager } from "../../core/dataManager";
import { mocked } from "ts-jest/utils";
import fs from "fs";
import sqlite3 from "sqlite3";
jest.mock("fs");
jest.mock("sqlite3");
let manager: DataManager;
const fake_database_path: string = "fake/database/path";
describe("datamanager.setup_db", () => {
beforeEach(() => {
jest.resetAllMocks();
manager = new DataManager();
manager.database_path = fake_database_path;
});
it("should create a new database file if one does not exist", async () => {
//Arrange
mocked(fs).existsSync = jest.fn().mockReturnValue = false as any;
mocked(sqlite3).Database = jest.fn() as any;
//Act
await manager.setup_db(fake_database_path);
});
});
I'm just not sure what on earth is preventing sqlite3 from finding its own package.json. None of my other dependencies seem to cause a fuss, yet sqlite3 does.
I need to call module from main index.js File
Here is my module
const request = require('./rq.js');
const callback = require('./callback.js')
const url = `https://localhost.3000/${id}`;
request(url, callback)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
})
module.exports = page; //Tell me how to export all code from module
So here is my index.js file
const Methods = {
page: require('./page.js'),
}
module.exports = //What i need to code here?
File from what i give a call a module :
const main = require('./index.js');
main.page({id: 'id'})
.then(console.log);
So what I should change to call page.js file like that ?
Make the following changes to page.js since in your main file you expect a promise to be returned.
const request = require('./rq.js');
const callback = require('./callback.js')
function page({id}) {
const url = `https://localhost.3000/${id}`;
return request(url, callback)
}
module.exports = {page: page} //Tell me how to export all code from module
Make the following changes to Mehods.js
const Methods = {
page: require('./page.js').page,
}
module.exports = Methods;
Check if this works.
I'm using the proxyquire library, which mocks packages on import.
I'm creating my own proxyquire function, which stubs a variety of packages I use regularly and want to stub regularly (meteor packages, which have a special import syntax):
// myProxyquire.js
import proxyquire from 'proxyquire';
const importsToStub = {
'meteor/meteor': { Meteor: { defer: () => {} } },
};
const myProxyquire = filePath => proxyquire(filePath, importsToStub);
export default myProxyquire;
Now I want to write a test of a file which uses one of these packages:
// src/foo.js
import { Meteor } from 'meteor/meteor'; // This import should be stubbed
export const foo = () => {
Meteor.defer(() => console.log('hi')); // This call should be stubbed
return 'bar';
};
And finally I test it like this:
// src/foo.test.js
import myProxyquire from '../myProxyquire';
// This should be looking in the `src` folder
const { foo } = myProxyquire('./foo'); // error: ENOENT: no such file
describe('foo', () => {
it("should return 'bar'", () => {
expect(foo()).to.equal('bar');
});
});
Note that my last 2 files are nested inside a subfolder src. So when I try to run this test, I get an error saying that the module ./foo couldn't be found, as it is being looked for in the "root" directory, where the myProxyquire.js file is, not the src directory as expected.
You might be able to work around that (expected) behaviour by using a module like caller-path to determine from which file myProxyquire was called, and resolving the passed path relative to that file:
'use strict'; // this line is important and should not be removed
const callerPath = require('caller-path');
const { dirname, resolve } = require('path');
module.exports.default = path => require(resolve(dirname(callerPath()), path));
However, I have no idea of this works with import (and, presumably, transpilers).
Isomorphic React
I would like to transpile my react components server side into one bundle.min.js file. The issue I am having is that the file doesn't resolve import statements.
This is the file I would like to transpile (client/component.js)
import React from 'react';
import ReactDom from 'react-dom';
import App from './components/app';
ReactDom.render(<App />, document.getElementById('app'));
The result is this (bundle.min.js)
'use strict';
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _app = require('./components/app');
var _app2 = _interopRequireDefault(_app);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_reactDom2.default.render(_react2.default.createElement(_app2.default, null), document.getElementById('app'));
But this is not what I want.
Files I require
I need all the import statements removed and replaced with the actual files that I need. In my case I require
some files from node modules
some component files
Gulp function so far
// builds the components and clientside
gulp.task('buildComponentsClient', () =>
gulp.src(['./client/*.js'])
.pipe(include()).on('error', console.log)
.pipe(babel({ presets: ['es2015', 'react']}))
.pipe(concat('bundle.js'))
// .pipe(uglify({mangle: false}))
.pipe(rename('bundle.min.js'))
.pipe(gulp.dest('./public'))
);
Question
How do i create a browser friendly file with all dependencies that are specified in these minimalistic react element files?
From what I understand you wan't to use browserify coupled with babelify. Here is my gulp task for this:
import gulp from 'gulp';
import glob from 'glob';
import browserify from 'browserify';
import babelify from 'babelify';
import rename from 'gulp-rename';
import source from 'vinyl-source-stream';
import es from 'event-stream';
import uglify from 'gulp-uglify';
import buffer from 'vinyl-buffer';
const path = './client/';
const files = '*.js';
const bundles = [path + files]; // I use an array to be able to bundle
// multiple paths within the same task
gulp.task('bundle', () => {
let bundleAll = bundles.map(bundle);
return Promise.all(bundleAll); // Task ends when all bundles are done
});
// Bundle files found in bundlePath, returns a Promise resolved
// when all files have been processed
function bundle(bundlePath) {
return new Promise((resolve, reject) => {
glob(bundlePath, (err, files) => { // Create glob from path
var tasks = files.map(file => { // loop through each file
return browserify(file) // pass it to browserify
.transform(babelify, ["es2015", "react"]) // using babelify (browserify + babel)
.bundle() // ..profit!
.on('error', err => {
console.error('err', err.toString());
reject(err);
})
.pipe(source(file)) // this is required for browserify output to be use as a gulp stream
.pipe(buffer()) // needed by gulp-uglify
.pipe(uglify())
.pipe(rename({ 'bundle.min.js' }))
.pipe(gulp.dest('./public'));
});
es.merge(tasks).on('end', resolve); // When all files have been processed, resolve the promise we returned
});
});
}