I am trying to write test using a class , but I am getting an error.
Here is the test:
import assert from 'assert'
const ethers = require('ethers');
const zksync = require('zksync');
const ZKSync = require('../../../../app/scripts/controllers/zksync');
describe('zkSync', function () {
let zkSync
before(async () => {
// zkSync = new ZKSync(new Proxy({}, ethers, zksync))
zkSync = new ZKSync(ethers, zksync);
})
describe('initAccount', function () {
it('registers an account on zksync', async () => {
const TEST_SEED = 'debris dizzy just program just float decrease vacant alarm reduce speak stadium'
const ethersProvider = await new ZKSync.getEthereumProvider(ethers,'rinkeby')
const zkSyncProvider = await new ZKSync.getZkSyncProvider('testnet');
const aliceRinkebyWallet = new ethersProvider.Wallet.fromMnemonic(TEST_SEED);
const aliceZKsyncWallet = new ZKSync.initAccount(aliceRinkebyWallet,zkSyncProvider);
assert.strictEqual(await aliceZKsyncWallet.isSigningKeySet(), true, 'account is registered.')
})
})
})
Here is the code it calls:
const ethers = require('ethers')
const zksync = require('zksync')
export default class ZKSync {
constructor (ethers, zksync) {
// const initState = opts.initState || {}
// this.store = new ObservableStore(initState)
// this.keyringController = opts.keyringController
this.ethers = ethers
this.zksync = zksync
}
async getZkSyncProvider (zksync, networkName) {
let zkSyncProvider
try {
zkSyncProvider = await zksync.getDefaultProvider(networkName)
} catch (error) {
console.log('Unable to connect to zkSync.')
console.log(error)
}
return zkSyncProvider
}
async getEthereumProvider (ethers, networkName) {
let ethersProvider
try {
// eslint-disable-next-line new-cap
ethersProvider = new this.ethers.getDefaultProvider(networkName)
} catch (error) {
console.log('Could not connect to Rinkeby')
console.log(error)
}
return ethersProvider
}
async initAccount (rinkebyWallet, zkSyncProvider) {
const zkSyncWallet = await this.zksync.Wallet.fromEthSigner(rinkebyWallet, zkSyncProvider)
return zkSyncWallet
}
}
I run the tests with mocha test/unit/app/controllers/zksync-lib-test.js.
However , I get the following error:
TypeError: ZKSync is not a constructor
I will appreciate any pointers on this.
Related
I need a transaction that prevents duplicate order numbers, this is my code:
ThrowError :
export class InsertRejectError extends Error {
constructor(msg?: string) {
super(msg)
Object.setPrototypeOf(this, GetInvoiceLargestNumberError.prototype)
}
}
Service:
async getInvoiceLargestNumber() {
// //transaction -------------------------------------------------
const isolationLevel = "serializable";
const trx = await this.knex.transaction({ isolationLevel })
//transaction -------------------------------------------------
try {
const invoiceLargestNumber = await trx
.select('invoiceNumber', 'id')
.from('invoice')
.orderBy('invoiceNumber', 'desc')
.limit(1)
.returning('invoiceNumber')
const invoiceLargestNumberString = invoiceLargestNumber[0].invoiceNumber//expect 'ABC003'
const invoiceLargestNumberNumber = Number(invoiceLargestNumberString.substring(3, invoiceLargestNumberString.length))//3
const invoiceLargestNumberNextNumber = invoiceLargestNumberNumber + 1 //4
const invoiceLargestNumberNextString = 'ABC00' + invoiceLargestNumberNextNumber.toString() //'ABC004'
await trx.commit()
return invoiceLargestNumberNextString
} catch (error) {
await trx.rollback()
throw new GetInvoiceLargestNumberError()
}
}
Test Case
it('can not getInvoiceLargesNumber (GetInvoiceLargestNumberError)', async () => {
//Act
try {
const promise1 = invoiceService.getInvoiceLargestNumber()
const promise2 = invoiceService.getInvoiceLargestNumber()
await Promise.all([promise1, promise2]);
// console.log(invoice)
fail()
//Assert
} catch (err) {
expect(err).toBeInstanceOf(GetInvoiceLargestNumberError)
}
})
How do I know that my knex transaction is working? The test case doesn't seem to trigger the race conditions correctly.
I expect to get GetInvoiceLargestNumberError.
get error
I have tried to mock the redisClient.js using redis-mock using jest. But I couldn't find the solution for it. please give me a code sample for it. I need to mock it in controller.
redisClient.js
const redis = require('redis');
const asyncRedis = require("async-redis");
//Redis
const connection = redis.createClient(process.env.REDIS_PORT,
{
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
// End reconnecting on a specific error and flush all commands with
// a individual error
return new Error("The server refused the connection");
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
return new Error("Retry time exhausted");
}
if (options.attempt > 10) {
// End reconnecting with built in error
return undefined;
}
// reconnect after
return Math.min(options.attempt * 100, 3000);
},
}
);
module.exports = asyncRedis.decorate(connection);
Controller
const logger = require('../../helper/logger');
const response = require("../../config/response");
const constant = require('../../config/constant');
const QuizService = require('../../services/quiz/quizService');
class QuizController {
constructor() {
this.quizService = new QuizService();
}
async getQuiz(req, res) {
const { userId, query: { campaignId } } = req;
try {
const question = await this.quizService.getQuestion(userId, campaignId);
res.send(response.res(true, constant.MSG.Quiz_FETCHED, question));
} catch (error) {
res.status(constant.RESPONSE.INTERNAL_ERROR.CODE)
.send(response.res(false, error.message, null, error.code))
}
}
}
Service
const _ = require('lodash');
const moment = require('moment');
const { Op } = require('sequelize');
const { v4: uuidv4 } = require("uuid");
const shuffle = require('shuffle-array');
const serialize = require("serialize-javascript");
const utill = require("../../helper/util");
const redis = require("../../cache/redisClient");
const constant = require('../../config/constant');
const scoreHelper = require('./../../helper/scoreHelper');
const db = require("../../models");
const Quiz = db.quiz;
const Campaign = db.campaign;
const campaign = require('../campaign/campaignService')
const SubscriberAnswer = require('../subscriberAnswer/subscriberAnswerService')
const SubscriberProgram = require('../subscriberProgram/SubsciberProgramService')
class quizService {
constructor() {
this.subscriberAnswer = new SubscriberAnswer()
this.subscriberProgram = new SubscriberProgram()
this.campaign = new campaign()
}
async getQuestion(userId, campaignId) {
const subscribedProgramData = await this._checkAvailableQuestionLimit(userId, campaignId)
if(!subscribedProgramData){
throw { message: constant.MSG.TRY_AGAIN }
}
if (subscribedProgramData.no_of_questions > 0) {
const question = await Quiz.findQuestion(userId, campaignId);
if (question.length) {
const data = {
subscriber_id: userId,
campaign_id: campaignId,
questions_id: question[0].id
}
const updateData = {
id: subscribedProgramData.id,
no_of_questions: (subscribedProgramData.no_of_questions - 1)
}
await this.subscriberAnswer.create(data);
await this.subscriberProgram.updateQuota(updateData);
const id = uuidv4();
const {answer, ...questionData } = question[0];
const responseData = await this.handleQuestionData(id, userId, campaignId, questionData, answer);
return responseData;
} else {
throw { code:constant.RESPONSE_COEDES.ALL_ANSWERED, message: constant.MSG.ANSWER_ALL }
}
} else {
throw { message: constant.MSG.QUOTA_OVER }
}
}
}
My Unit Testing Code
const QuizService = require("../../src/services/quiz/quizService");
const QuizController = require("../../src/controllers/quiz/quizController");
const quizService = new QuizService();
const quizController = new QuizController();
const httpMocks = require("node-mocks-http");
jest.mock("../../src/helper/logger");
jest.mock("../../src/cache/redisClient.js");
beforeEach(() => {
req = httpMocks.createRequest();
res = httpMocks.createResponse();
next = jest.fn();
jest.resetAllMocks();
quizService.getQuestion = jest.fn();
});
quizService.getQuestion = jest.fn();
const response = {
id: 1,
name: 'Sandun',
msisdn: '94704377575',
otp: '1234',
deleted: 0,
attempts: 0,
img_url: 'https://'
}
// This test shows how the constructor can be mocked, and how to spy on passed parameters.
describe("Test QuizController", () => {
afterEach(() => {
jest.resetAllMocks();
});
//Because getQuestion is prototype method
it("Test - GetQuiz - Success", async () => {
req.query.programId = 1;
req.userId = 1;
jest.spyOn(QuizService.prototype, "getQuestion").mockReturnValue(response);
await quizController.getQuiz(req, res);
expect(res.statusCode).toBe(200);
});
});
ERROR
FAIL test/controllers/quiz.controller.test.js
● Test suite failed to run
TypeError: Cannot read property 'startsWith' of undefined
//Redis
const connection = redis.createClient(process.env.REDIS_PORT,
^
{
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
at normalizeUrl (node_modules/redis-mock/lib/utils/parseRedisUrl.js:4:11)
at Object.<anonymous>.module.exports (node_modules/redis-mock/lib/utils/parseRedisUrl.js:61:34)
at generateUrlOptions (node_modules/redis-mock/lib/client/createClient.js:25:30)
at unifyOptions (node_modules/redis-mock/lib/client/createClient.js:61:10)
at Object.createClient (node_modules/redis-mock/lib/client/createClient.js:64:47)
at Object.<anonymous> (src/cache/redisClient.js:5:26)
at Object.<anonymous> (src/services/quiz/quizService.js:8:15)
at Object.<anonymous> (test/controllers/quiz.controller.test.js:1:21)
I have developed the node js code as MVC architecture. The folder structure is Controller --> service -> model. And I have tried to write unit testing for the following code. Unfortunately, I couldn't mock the service function. So please help me to resolve it.
Controller
const SubscriberService = require('../../services/subscriber/subscriberService')
const response = require("../../config/response");
const constant = require('../../config/constant');
const SubscriberAnswerService = require('../../services/subscriberAnswer/subscriberAnswerService');
const path = require('path');
class SubscriberController {
constructor() {
this.subscriberService = new SubscriberService();
this.subscriberAnswerService = new SubscriberAnswerService();
}
async getSubscriber(req, res) {
try {
var { userId } = req;
const user = await this.subscriberService.findByUserId(userId);
if (user != null) {
res.send(response.res(true, constant.MSG.USER_DETAILS, user))
} else {
res.status(404).send(response.res(false, constant.MSG.USER_NOT_FOUND));
}
} catch (error) {
res.status(constant.RESPONSE.INTERNAL_ERROR.CODE)
.send(response.res(false, error.message))
}
}
}
Service
async findByUserId(id) {
const user = await Subscriber.findOne({ where: { id: id, status: 1 } });
return user;
}
Unit Testing Code
describe("Test SubscriberController", () => {
it("Test getsubscriber", async () => {
req.userId = 1;
jest.spyOn(subscriberService, "findByUserId").mockReturnValue(subscriberResponse);
await subscriberController.getSubscriber(req, res);
expect(res.statusCode).toBe(500);
});
});
Issue: I have mocked the service function which findByUserId but it does not work. It is given the following error.
error TypeError: Cannot read property 'findOne' of undefined
Please give the solution to mock findByUserId function.
Subscriber.Controller.test.js
const subscriberModel = require("../src/models/subscriber/subscriberModel");
const SubscriberService = require("../src/services/subscriber/subscriberService");
const SubscriberController = require("../src/controllers/Subscriber/subscriberController");
const subscriberController = new SubscriberController();
const subscriberService = new SubscriberService();
const httpMocks = require("node-mocks-http");
jest.mock("../src/models/subscriber/subscriberModel");
beforeEach(() => {
jest.resetAllMocks();
req = httpMocks.createRequest();
res = httpMocks.createResponse();
next = jest.fn();
jest.resetAllMocks();
subscriberModel.findOne = jest.fn();
});
// subscriberService.findByUserId = jest.fn();
const subscriberResponse = {
id: 1,
name: 'Sandun',
msisdn: '94704377575',
otp: '1234',
deleted: 0,
attempts: 0,
img_url: 'https://'
}
jest.mock('../src/models/subscriber/subscriberModel', () => () => {
const SequelizeMock = require("sequelize-mock");
let dbMock = new SequelizeMock();
let subscriberMock = dbMock.define('subscribers', {
id: 1,
name: 'Sandun',
msisdn: '94704377575',
otp: '1234',
deleted: 0,
attempts: 0,
img_url: 'https://'
});
let groupMock = dbMock.define('winner', {});
subscriberMock.belongsTo(groupMock);
subscriberMock.hasMany();
});
// This test shows how the constructor can be mocked, and how to spy on passed parameters.
describe("Test SubscriberController", () => {
it("Test getsubscriber", async () => {
req.userId = 1;
jest.spyOn(subscriberService, "findByUserId").mockReturnValue(subscriberResponse);
await subscriberController.getSubscriber(req, res);
expect(res.statusCode).toBe(200);
});
});
disclaimer: this is part of a course I am taking and a practice task. I am having quite hard time wrapping my head around the test chapter of a course I am taking. Given the following class, I have to write test to it but I see the error else path not taken on my return results; line. Which else is it talking about?
import DB from './DB';
import ErrorLogger from './ErrorLogger'; // ===> if path not taken here
class ChapterSevenJest {
constructor() {
if (!ChapterSevenJest.instance) {
ChapterSevenJest.instance = this;
}
return ChapterSevenJest.instance;
}
_db = new DB();
getData = async (gradeId, teamId) => {
let results = [];
try {
results = await this._db.getData(gradeId, teamId);
} catch (error) {
ErrorLogger.register(
error
);
}
return results; // else path not taken here
};
}
const JestPractice = new ChapterSevenJest();
export default JestPractice;
the test:
import DB from './DB';
import ErrorLogger from './ErrorLogger';
import JestPractice from './JestPractice';
describe('service', () => {
const gradeId = 11;
const teamId = 1;
let spyLogs;
beforeEach(() => {
spyLogs = jest.spyOn(ErrorLogger, 'register');
spyLogs.mockReturnValue(true);
});
afterEach(() => {
spyLogs.mockReset();
});
it('should return data ot a grade and team', async () => {
const spyDB = jest.spyOn(
DB.prototype,
'getData'
);
const stat = [
{
"score" : 100,
"rank": 2
}
]
spyDB.mockResolvedValue(stat);
const results = await JestPractice.getData(
gradeId,
teamId
);
expect(spyDB).toHaveBeenCalledWith(gradeId, teamId);
expect(results).toHaveLength(1);
expect(results[0].score).toStrictEqual(100);
expect(results[0].rank).toStrictEqual(2);
});
it('should return empty on error', async () => {
const spyDB = jest.spyOn(
DB.prototype,
'getData'
);
spyDB.mockRejectedValue('error');
const results = await JestPractice.getData(
gradeId,
teamId
);
expect(spyDB).toHaveBeenCalledWith(gradeId, teamId);
expect(results).toHaveLength(0);
expect(spyLogs).toHaveBeenCalledWith(
"error"
);
});
});
There is only 1 if statement which is
if (!ChapterSevenJest.instance) {
ChapterSevenJest.instance = this;
}
You need to have a test where ChapterSevenJest.instance is truthy so that the if block doesn't execute.
i have a problem with my project, i need sharing the configurations parameters between modules, y have my entry point
app.js
const { requestConfiguracion } = require('./clases/servicios');
( async () => {
const dbConfig = await requestConfiguracion();
})();
servicios.js
const axios = require('axios').default;
const requestConfiguracion = async () => {
try {
const request = await axios.get('http://localhost/config/getConfig');
return request.data;
} catch (error) {
console.error(error)
}
}
module.exports = {
requestConfiguracion,
}
I need that the configuration in dbConfig is available for the other modules.
You can create a separated module to read and export that dbConfig.
// db-config.js
const { requestConfiguracion } = require('./clases/servicios');
let dbConfig = null;
module.exports.getDbConfig = async () => {
if (dbConfig) return dbConfig; // cache dbConfig for next time
dbConfig = await requestConfiguracion();
return dbConfig;
};
And in other modules:
// app.js
const { getDbConfig } = require('./db-config');
async function someFunction() {
const dbConfig = await getDbConfig();
// do something
}
Since your requestConfiguracion() function is an async function, you have to use await every time trying to get that config.