What is the true meaning of `Contract.at()` - truffle

Here is my test code, I am trying to understand the meaning of Contract.at() function.
As you can see, I have insert the code to mockAddress, but when I call the Hello.at(mockAddress) function, it throws exception Error: Cannot create instance of Hello; no code at address 0xe2d3A739EFFCd3A99387d015E260eEFAc72EBea1. Feel really strange. Any idea, where am I wrong?
const Hello = artifacts.require("hello/Hello");
contract("Hello test code", async function () {
it("Contract.at", async function () {
const mockAddress = "0xe2d3A739EFFCd3A99387d015E260eEFAc72EBea1";
const code =
"0x6080604052348015600f57600080fd5b50603f80601d6000396000f3fe6080604052600080fdfea264697066735822122017a2ce05533e864d9273119636089adc9ee39f4de7f45ce1cf3d069a136fe25d64736f6c634300080e0033";
const setStatus = await provider.request({
method: "evm_setAccountCode",
params: [mockAddress, code],
});
assert.strictEqual(setStatus, true);
const getCode = await provider.request({
method: "eth_getCode",
params: [mockAddress],
});
assert.strictEqual(code, getCode);
let mockContract = await Hello.at(mockAddress);
});
});
Error: Cannot create instance of Hello; no code at address 0xe2d3A739EFFCd3A99387d015E260eEFAc72EBea1
at Object.checkCode (node_modules/truffle/build/webpack:/packages/contract/lib/utils/index.js:272:1)
at Function.at (node_modules/truffle/build/webpack:/packages/contract/lib/contract/constructorMethods.js:73:1)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at Context.<anonymous> (test/merchant/Hello.test.js:21:24)

Related

How to test next parameter in controller using mocha and chai

I've got a controller which I'm using the 'next' parameter, and I have no idea how to include it into the test. I've done request and response, everything is ok, but when I use the next, I've got the error asking for the 3rd argument. How to test 'next' in this case?
error
Expected 3 arguments, but got 2.ts(2554)
car.controller.ts(20, 5): An argument for 'next' was not provided.
controller test
describe('Cars Controller Tests', () => {
const carModel = new CarModel();
const carService = new CarService(carModel);
const carController = new CarController(carService);
const req = {} as Request;
const res = {} as Response;
before(async () => {
sinon.stub(carService, 'create').resolves(mock.carMockWithId);
res.status = sinon.stub().returns(res);
res.json = sinon.stub().returns(res);
});
after(()=>{
sinon.restore();
})
it('1 - CREATE runs successfully', async () => {
req.body = mock.carMock;
await carController.create(req, res);
expect((res.status as unknown as sinon.SinonStub).calledWith(201)).to.be.true;
expect((res.json as sinon.SinonStub).calledWith(mock.carMockWithId)).to.be.true;
});
});
I just got from an article I found:
declare Next then test as usual:
const req = {} as Request;
const res = {} as Response;
const next = {} as NextFunction;
....
await carController.create(req, res, next);

Unable to stub an exported function with Sinon

I need to test the following createFacebookAdVideoFromUrl() that consumes a retryAsyncCall that I'd like to stub with Sinon :
async function createFacebookAdVideoFromUrl(accountId, videoUrl, title, facebookToken = FACEBOOK_TOKEN, options = null, businessId = null) {
const method = 'POST';
const url = `${FACEBOOK_URL}${adsSdk.FacebookAdsApi.VERSION}/${accountId}/advideos`;
const formData = {
access_token: businessId ? getFacebookConfig(businessId).token : facebookToken,
title,
name: title,
file_url: videoUrl,
};
const callback = () => requestPromise({ method, url, formData });
const name = 'createFacebookAdVideoFromUrl';
const retryCallParameters = buildRetryCallParameters(name, options);
const adVideo = await retryAsyncCall(callback, retryCallParameters);
logger.info('ADVIDEO', adVideo);
return { id: JSON.parse(adVideo).id, title };
}
This retryAsyncCall function is exported as such:
module.exports.retryAsyncCall = async (callback, retryCallParameters, noRetryFor = [], customRetryCondition = null) => {
// Implementation details ...
}
Here is how I wrote my test so far:
it.only("should create the video calling business's Facebook ids", async () => {
const payload = createPayloadDataBuilder({
businessId: faker.internet.url(),
});
const retryAsyncCallStub = sinon.stub(retryAsyncCallModule, 'retryAsyncCall').resolves('random');
const createdFacebookAd = await FacebookGateway.createFacebookAdVideoFromUrl(
payload.accountId,
payload.videoUrl,
payload.title,
payload.facebookToken,
payload.options,
payload.businessId,
);
assert.strictEqual(retryAsyncCallStub.calledOnce, true);
assert.strictEqual(createdFacebookAd, { id: 'asdf', title: 'asdf' });
});
I don't expect it to work straightaway as I am working in TDD fashion, but I do expect the retryAsyncCall to be stubbed out. Yet, I am still having this TypeError: Cannot read property 'inc' of undefined error from mocha, which refers to an inner function of retryAsyncCall.
How can I make sinon stubbing work?
I fixed it by changing the way to import in my SUT :
// from
const { retryAsyncCall } = require('../../../helpers/retry-async');
// to
const retry = require('../../../helpers/retry-async');
and in my test file :
// from
import * as retryAsyncCallModule from '../../../src/common/helpers/retry-async';
// to
import retryAsyncCallModule from '../../../src/common/helpers/retry-async';
The use of destructuring seemed to make a copy instead of using the same reference, thus, the stub was not applied on the right reference.

sinon stub calls fake calling actual function

I'm having situation where I want to write unit test cases for a function to make sure if it is working fine or not. So I have created stub for that specific function and when I tries to calls fake that stub, the function is actually getting called instead of fake call. Below is my scenario:
I have an main function from where I'm calling the function saveData(**).
saveData(**) function is calling AWS SQS to save an message to DB
Below is my main function:
'use strict';
async function mainFunction() {
try {
await saveData(
name,
age,
);
return true;
} catch (e) {
console.log('Error - [%s]', e);
return null;
}
}
module.exports = { mainFunction };
Below is my saveData(**) function:
'use strict';
const AWS = require('aws-sdk');
const sqs = new AWS.SQS();
const saveData = async (
name,
age,
) => {
await sendMessage(JSON.stringify(dbData));
const params = {
DelaySeconds: <some_delay>,
MessageAttributes: <messageAttributes>,
MessageBody: {name:name, age:age},
QueueUrl: <URL_FOR_QUEUE>,
};
return sqs.sendMessage(params).promise();
return true;
};
module.exports = {
saveData,
};
And my test case is,
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
require('app-module-path').addPath('./src');
const sinon = require('sinon');
const app = express();
const sqsSender = require('lib/queue');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const main = require('../../../src/main-function');
const routes = require('routes');
routes.configure(app);
let mainFunctionStub;
let saveDataStub;
describe('/v1/main', () => {
beforeEach(() => {
mainFunctionStub = sinon.stub(main, 'mainFunction');
saveDataStub = sinon.stub(sqsSender, 'saveData');
});
describe('Test', () => {
it(`should return success`, (done) => {
const name = 'Name';
const age = 'Age';
saveDataStub.resolves({
name,
age,
});
});
});
afterEach(() => {
mainFunctionStub.restore();
mainFunctionStub.reset();
saveDataStub.restore();
saveDataStub.reset();
});
});
But this test is returning,
error: Jun-20-2021 20:07:05: Error - [Error [ConfigError]: Missing region in config
and,
Error: Timeout of 3500ms exceeded.
From this error I can say that this is actually calling SQS function instead of faking. How can I resolve this or how can I fake call to this function? I'm new to this unit testing so any help would be appriciated.
Stubbing works by replacing the property on the exports object. Since the require happens before sinon replaces the function, you capture the reference to the original function instead of dynamically using the currently set one.
You haven't showed your require calls in the main file, but from the call-site I infer you're importing it like const { saveData } = require('../foo/sqsSender'). This means you're grabbing the function off of the object when first loading the code. If you instead keep a reference to the sqsSender module instead, and reference the function on invocation, the stub should work.
'use strict';
// Don't destructure / grab the function.
const sqsSender = require("../foo/sqsSender")+
async function mainFunction() {
try {
// Use reference through module
await sqsSender.saveData(
name,
age,
);
return true;
} catch (e) {
console.log('Error - [%s]', e);
return null;
}
}
module.exports = { mainFunction };

Firebase ReferenceError: PostData is not defined

I am trying to create an elastic search cloud Firebase function but am having some error in the firebase functions. The error references to the index.js code but i don't know where am going wrong. Where could i have gone wrong in the index.js code??
const functions = require('firebase-functions');
const request = require('request-promise')
exports.indexPostsToElastic = functions.database.ref('/posts/{post_id}')
.onWrite((change,context) =>{
let postData = change.after.val();
let post_id = context.params.post_id;
console.log('Indexing post',PostData);
let elasticSearchConfig = functions.config().elasticSearch;
let elasticSearchUrl = elasticSearchConfig.Url + 'posts/' + post_id;
let elasticSearchMethod = postData ? 'POST' : 'DELETE';
let elasticSearchRequest = {
method:elasticSearchMethod,
url: elasticSearchUrl,
auth:{
username : elasticSearchConfig.username,
password : elasticSearchConfig.password,
},
body: postData,
json : true
};
return request(elasticSearchRequest).then(response => {
return console.log("ElasticSearch response", response);
})
});
Below is how the error reads in my Firebase
ReferenceError: PostData is not defined
at exports.indexPostsToElastic.functions.database.ref.onWrite (/user_code/index.js:10:31)
at cloudFunctionNewSignature (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:114:23)
at cloudFunction (/user_code/node_modules/firebase-functions/lib/cloud-functions.js:144:20)
at /var/tmp/worker/worker.js:827:24
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
I expect the function execution to finish withe status successful but its finishing with an error.
Change this:
console.log('Indexing post', PostData);
Into this:
console.log('Indexing post', postData);

simple ProxyRequire is not working?

i have been stuck with making Proxy-require work, below is my code and test file. I am trying to stub a function inside the code file using proxyRequire
//createSignature.js
'use strict';
var keys = require('../../../../utils/keys');
module.exports = function createSignature(transaction) {
try {
let prvkeyDecoded = keys.bs58_encode('test');
return true
} catch (err) {
}
};
here is the test file
//createSignature_unit.js
'use strict';
const sinonChai = require("sinon-chai");
const chai = require('chai');
chai.use(sinonChai);
const sinon = require('sinon');
const createSignature = require('./createSignature');
const proxyquire = require('proxyquire').noPreserveCache().noCallThru();
const keysMock =
{
bs58_encode: sinon.stub()
};
const test =
proxyquire('./createSignature', {
'../../../../utils/keys': keysMock
})
describe('test backend', () => {
it("Create Signature with stubs", function() {
test('test')
expect(keysMock.bs58_encode).to.have.been.calledOnce;
});
});
my test function is not called, and keysMock.bs58_encodealso is not been called even once. Am i missing something?
//output window
1) Create Signature with stubs
0 passing (9ms)
1 failing
1) test backend
Create Signature with stubs:
AssertionError: expected stub to have been called exactly once, but it was called 0 times
at Context.<anonymous> (createSignature_unit.js:37:46)
In addition to this if i just call
it("Create Signature with stubs", function() {
expect(test('fg')).to.be.true
//expect(keysMock.bs58_encode).to.have.been.calledOnce;
});
i get output as AssertionError: expected undefined to be true
Your stub wrong function as mock. In test, you stub bs58_encode but in the source file, you use bs58_decode. Change it into bs58_decode should fix it.
const keysMock = {
bs58_decode: sinon.stub() // change to decode
};
const test =
proxyquire('./createSignature', {
'../../../../utils/keys': keysMock
})
describe('test backend', () => {
it("Create Signature with stubs", function () {
test('test')
expect(keysMock.bs58_decode).to.have.been.calledOnce; // change to decode
});
});

Resources