it("TEST", async function () {
let instanceOne = await ethers.getContractAt("IERC20", TOKEN_IN);
let instanceTwo = await ethers.getContractAt("IERC20", TOKEN_OUT);
let addr = contract.address;
// error
let val = await instanceOne.approve(addr, AMOUNT_IN, { from: WHALE });
Error: Contract with a signer cannot override from (operation="overrides.from", code=UNSUPPORTED_OPERATION, version=contracts/5.5.0)
Related
How to fix error?
There is a save method in my dao:
DeliveryLine.dao.ts:
import{Injectable}from"#nestjs/common";
impoet{InjectConnection}from "#nestjs/mongoose";
import{Connection}from "mongoose"
import{DeliveryLine, DeliveryLineSchema}from "../../mongo/schema/DeliveryLine.schema"
import{DeliveryLineFilterDto} from "../dto/DeliveryLineFilter.dto"
#Injectable()
export class DeliveryLineDao{
#InjectConnection("std")
private connection:Connection;
collectionName = DeliveryLine.collectionName;
schema = DeliveryLineSchema;
async save(model:DeliveryLine):Promise<DeliveryLine>{
let theModel = this.connection.model(this.collectionName,this.schema);
model.lastDate = new Date();
let doc = new theModel(model);
let newDoc = await doc.save().then((value)=>{return value.toObject();}).catch((e)=>{let errMsg = "save is called for:" + JSON.stringify(model) + "with error:" + e; throw new Error(e);});
return newDoc;
}
I want to test my function save to pass jest.
DeliveryLine.spec.ts:
import *as mongoose from "mongoose";
import{Test}from "#nestjs/testing";
import{DeliveryLine }from "../schema/DeliveryLine.schema";
import{DeliveryLineDao }from "./DeliveryLine.dao";
impoet{ConfigModule} from "#nestjs/config";
let service:DeliveryLineDao;
describe("test",()=>{
let deliveryLineInput ={
UUID:"UU1",
part:"1",
}
let connection = {
model:jest.fn(()=>{
return {
save:jest.fn().mockImplementation(()=>Promise.resolve(jest.fn().mockImplementation()).then(()=>({toObject:jest.fn().mockImplementation(()=>Promise.resolve(deliveryLineInput))}))),
};
}),
};
beforeEach(async () ={
const model = await Test.createTestingModule({
import:[ConfigModule.forRoot()],
provides:[DeliveryLineDao,{provide:"stdConnection",useValue:connection}],}).compile();
service = module.get<DeliveryLineDao>(DeliveryLineDao);
});
test("to save deliveryLine", async () =>{
let result = new DeliveryLine();
result = deliveryLineInput;
let deliveryLineSaved = await service.save(result);
export(deliveryLineSaved).toBeTruthy();
export(deliveryLineSaved).toBe(result);
});
})
})
My test is run error why did I run success for the test?
Jest test error:
TypeError: theModule is not a constructor
model.lastDate = new Date();
let doc = new theModel(model);
I am trying to develop a MS Teams bot that sends content to students module(unit) wise. I have created 3 classes:
methods.js = Contains all the methods for sending texts, attachments etc.
teamBot.js = Captures a specific keyword from the users and based on that executes a function.
test.js = Connects the bot with Airtable and sends the content accordingly
I am facing Cannot perform 'get' on a proxy that has been revoked error. I figured it might be because of the context. I am passing context as a parameter, which I feel might not be the correct way, how can I achieve the result, and retain the context between files.
teamsBot.js
const test = require("./test");
class TeamsBot extends TeamsActivityHandler {
constructor() {
super();
// record the likeCount
this.likeCountObj = { likeCount: 0 };
this.onMessage(async (context, next) => {
console.log("Running with Message Activity.");
let txt = context.activity.text;
// const removedMentionText = TurnContext.removeRecipientMention(context.activity);
// if (removedMentionText) {
// // Remove the line break
// txt = removedMentionText.toLowerCase().replace(/\n|\r/g, "").trim();
// }
// Trigger command by IM text
switch (txt) {
case "Begin": {
await test.sendModuleContent(context)
}
// By calling next() you ensure that the next BotHandler is run.
await next();
});
// Listen to MembersAdded event, view https://learn.microsoft.com/en-us/microsoftteams/platform/resources/bot-v3/bots-notifications for more events
this.onMembersAdded(async (context, next) => {
const membersAdded = context.activity.membersAdded;
for (let cnt = 0; cnt < membersAdded.length; cnt++) {
if (membersAdded[cnt].id) {
const card = cardTools.AdaptiveCards.declareWithoutData(rawWelcomeCard).render();
await context.sendActivity({ attachments: [CardFactory.adaptiveCard(card)] });
break;
}
}
await next();
});
}
test.js
const ms = require('./methods')
async function sendModuleContent(context) {
data = module_text //fetched from Airtable
await ms.sendText(context, data)
}
methods.js
const {TeamsActivityHandler, ActivityHandler, MessageFactory } = require('botbuilder');
async function sendText(context, text){
console.log("Sending text")
await context.sendActivity(text);
}
Refer this: TypeError: Cannot perform 'get' on a proxy that has been revoked
make the following changes to test.js
const {
TurnContext
} = require("botbuilder");
var conversationReferences = {};
var adapter;
async function sendModuleContent(context) {
data = module_text //fetched from Airtable
const currentUser = context.activity.from.id;
conversationReferences[currentUser] = TurnContext.getConversationReference(context.activity);
adapter = context.adapter;
await adapter.continueConversation(conversationReferences[currentUser], async turnContext => {
await turnContext.sendActivity(data);
});
}
I'm new to Node and I'm trying to test a TypeORM custom Repository with Mocha and Sinon, without hitting the database.
My Repository has a method that takes 2 parameters and returns a Promise. It uses a local query builder and I would like to spy it (the queryBuilder) to know how many times its methods are called. This is my custom Repository:
#EntityRepository(Pratica)
export class PraticaRepository extends Repository<Pratica> {
list(targa?: string, tipoVeicolo?: string): Promise<Pratica[]> {
fileLogger.log('info','inizio - targa: %s; tipoVeicolo %s.', targa, tipoVeicolo);
let queryBuilder: SelectQueryBuilder<Pratica> = this.createQueryBuilder("p")
.leftJoinAndSelect("p.stato", "stato")
.leftJoinAndSelect("p.microstato", "microstato");
let filtered: boolean = false;
if(targa && targa !== ""){
fileLogger.debug("Applico filtro targa");
filtered = true;
queryBuilder.where("p.targa = :targa", {targa: targa});
}
if(tipoVeicolo && tipoVeicolo !== ""){
if(!filtered){
fileLogger.debug("Applico filtro tipoVeicolo");
filtered = true;
queryBuilder.where("p.tipoVeicolo = :tipoVeicolo", {tipoVeicolo: tipoVeicolo});
}else{
fileLogger.debug("Applico filtro tipoVeicolo come parametro aggiuntivo");
queryBuilder.andWhere("p.tipoVeicolo = :tipoVeicolo", {tipoVeicolo: tipoVeicolo});
}
}
fileLogger.log('debug', "Sql generato: %s", queryBuilder.getSql);
fileLogger.info("fine");
return queryBuilder.getMany();
}
I've tryed something like the following:
describe('PraticaRepository#list', () => {
it.only('should call getMany once', async () => {
let result = new Promise((resolve,reject) => {
resolve(new Array(new Pratica(), new Pratica()))
});
let getMany = sinon.stub().returns(result);
typeorm.createQueryBuilder = sinon.stub().returns({
select: sinon.stub(),
from: sinon.stub(),
leftJoinAndSelect: sinon.stub(),
where: sinon.stub(),
orderBy: sinon.stub(),
getMany: getMany
})
let cut = new PraticaRepository();
const appo = cut.list('','');
sinon.assert.calledOnce(getMany);
});
})
But obviously i get the following error:
1) PraticaRepository#list
should call getMany once:
TypeError: Cannot read property 'createQueryBuilder' of undefined
at PraticaRepository.Repository.createQueryBuilder (src\repository\Repository.ts:50:29)
at PraticaRepository.list (src\repositories\PraticaRepository.ts:12:62)
because the query builder I'm stubbing is not the one instantiated inside the Repository method. My questions:
Is it possible to spy a method like this?
Is this method "Unit Testable"? Or should I test it only against some functional/integration test.
Thank you in advance.
Thanks to the suggestions of #oligofren this is my final solution:
let sandbox;
let createQueryBuilderStub;
let mock;
let fakeQueryBuilder = new SelectQueryBuilder<Pratica>(null);
beforeEach(() => {
sandbox = sinon.createSandbox();
mock = sandbox.mock(fakeQueryBuilder);
createQueryBuilderStub = sandbox.stub(Repository.prototype,
'createQueryBuilder').withArgs("p").returns(fakeQueryBuilder);
});
afterEach(() => {
sandbox.restore();
});
describe('PraticaRepository#list', () => {
it('should get the result with no filters', async () => {
mock.expects('leftJoinAndSelect').twice().returns(fakeQueryBuilder);
mock.expects('where').never();
mock.expects('andWhere').never();
mock.expects('getSql').once();
mock.expects('getMany').once();
let cut = new PraticaRepository();
const appo = cut.list();
sinon.assert.calledOnce(createQueryBuilderStub);
mock.verify();
});
})
I am building a chatbot with WATSON API where I use the async/await method in order to fetch the data from MongoDB and attain the result, which then I send it back to the user.
The function artpromise is the promise that collects data from mongo DB. And the function randomartist is a function that fetches 3 random document from the DB. However, the WATSON BLUEMIX Cloud service supports Nodejs SDK of 6.1.3 which does not support the async method. Is there any way to update the SDK version on Blumix or should I use a difference approach in fetching data from the server?
let getConversationResponse = (message, context) => {
let payload = {
workspace_id: process.env.WORKSPACE_ID,
context: context || {},
input: message || {}
};
payload = preProcess(payload);
return new Promise((resolved, rejected) => {
// Send the input to the conversation service
conversation.message(payload, async function(err, data) {
if (err) {
rejected(err);
}
else{
if(data.context.type == 'ask'){
let artist = data.context.name;
let result = await artpromise(artist);
console.log(result);
data.context.name = result[0].name;
data.context.nationality = result[0].nationality;
data.context.birth = result[0].years;
data.context.url = result[0].art_link;
data.output.text = data.context.name+' is a '+data.context.nationality+' artist from '+data.context.birth+'. Check out a painting at '+data.context.url;
}
else if(data.context.type == 'random_artist'){
let result = await randomArtist();
console.log(result);
data.output.text = 'Let\'s find some random artists for you! \n'+result;
}
let processed = postProcess(data);
if(processed){
// return 값이 Promise 일 경우
if(typeof processed.then === 'function'){
processed.then(data => {
resolved(data);
}).catch(err => {
rejected(err);
})
}
// return 값이 변경된 data일 경우
else{
resolved(processed);
}
}
else{
// return 값이 없을 경우
resolved(data);
}
}
});
})
}
Using Node's util.promisify() utility, you can transform a callback-style function into a Promise-based one.
Somewhere outside of your getConversationResponse-function, assign it to a local variable:
const util = require('util');
const messagePromise = util.promisify(conversation.message);
And use that function instead. Something like this should work:
const util = require('util');
const messagePromise = util.promisify(conversation.message);
let getConversationResponse = async (message, context) => {
let payload = preprocess({
workspace_id: process.env.WORKSPACE_ID,
context: context || {},
input: message || {}
});
let data = await messagePromise(payload);
if (data.context.type == 'ask') {
let artist = data.context.name;
let result = await artpromise(artist);
console.log(result)
data.context.name = result[0].name;
data.context.nationality = result[0].nationality;
data.context.birth = result[0].years;
data.context.url = result[0].art_link;
data.output.text = data.context.name+' is a '+data.context.nationality+' artist from '+data.context.birth+'. Check out a painting at '+data.context.url;
} else if (data.context.type == 'random_artist'){
let result = await randomArtist();
console.log(result);
data.output.text = 'Let\'s find some random artists for you! \n'+result;
}
return postProcess(data) || data;
};
Note that if the return value of postProcess is falsy, it will return the data variable instead. Additionally, an async function always returns a Promise, so to call this function, you'll do:
getConversationResponse(message, context).then((data) => {
// Do something with the data
}).catch((e) => {
// Handle the error!
});
or if you call it from another async function:
let data = await getConversationResponse(message, context);
or if you need to specifically catch errors in the calling async function:
try {
let data = await getConversationResponse(message, context);
} catch (e) {
// Handle error
}
Just like regular synchronous code, any error thrown in the function call chain "trickles up" to the top-most callee. If you're confused about this, I suggest reading up on error handling.
If you want to use the Watson API in an async Promise-based fashion throughout your code, it might be feasible to write a small wrapper library and use that directly instead.
A Promise-only implementation:
const util = require('util');
const messagePromise = util.promisify(conversation.message);
let getConversationResponse = (message, context) => {
let payload = preprocess({
workspace_id: process.env.WORKSPACE_ID,
context: context || {},
input: message || {}
});
return messagePromise(payload).then((data) => {
if (data.context.type == 'ask') {
let artist = data.context.name;
return artpromise(artist).then((result) => {
data.context.name = result[0].name;
data.context.nationality = result[0].nationality;
data.context.birth = result[0].years;
data.context.url = result[0].art_link;
data.output.text = data.context.name+' is a '+data.context.nationality+' artist from '+data.context.birth+'. Check out a painting at '+data.context.url;
return data;
});
} else if (data.context.type == 'random_artist') {
return randomArtist().then((result) => {
data.output.text = 'Let\'s find some random artists for you! \n' + result;
return data;
});
}
}).then((data) => {
return postProcess(data) || data;
});
};
Calling it is the exact same as the async/await implementation.
I'm trying to get sinon.stub to work for async function. I have created promiseFunction.js:
let functionToBeStubbed = async function() {
return ("Text to be replaced by stub.");
};
let promiseFunction = async function() {
return(await functionToBeStubbed());
};
module.exports = {
promiseFunction: promiseFunction,
functionToBeStubbed: functionToBeStubbed
};
and test promiseFunction.spec.js:
let functionstobestested = require('./promiseFunction.js');
describe('Sinon Stub Test', function () {
var sandbox;
it('should return --Text to be replaced by stub.--', async function () {
let responsevalue = "The replaced text.";
sandbox = sinon.sandbox.create();
sandbox.stub(functionstobestested, 'functionToBeStubbed').resolves(responsevalue);
//sandbox.stub(functionstobestested, 'functionToBeStubbed').returns(responsevalue);
let result = "Empty";
console.log(`BEFORE: originaldata = ${result}, value = ${responsevalue}`);
result = await functionstobestested.promiseFunction();
console.log(`AFTER: originaldata = ${result}, value = ${responsevalue}`);
expect(result).to.equal(responsevalue);
sandbox.restore();
console.log("AFTER2: Return value after restoring stub: " + await functionstobestested.promiseFunction());
});
});
when running the test, I will get
test failure
If I modify export slightly, it still fails:
var functionsForTesting = {
promiseFunction: promiseFunction,
functionToBeStubbed: functionToBeStubbed
};
module.exports = functionsForTesting;
I do not understand why this test fails, as it should pass. If I change the way I export functions from promiseFunction.js - module, the test pass correctly. Revised promiseFunction.js:
const functionsForTesting = {
functionToBeStubbed: async function() {
return ("Text to be replaced by stub.");
},
promiseFunction: async function() {
return(await functionsForTesting.functionToBeStubbed());
};
module.exports = functionsForTesting;
Test pass
What's wrong in my original and modified way to export functions?