testing events sinon node.js - node.js

I want testing my function and I stuck with mocking events. I don't know how mock event with sinon.
This is my code when I stuck:
return pdfGenerator(invoice)
.then(content =>
{
const printer = new PdfMakePrinter(fonts);
let pdfDoc = {};
try {
pdfDoc = printer.createPdfKitDocument(content);
} catch (error) {
throw applicationException.new(applicationException.ERROR, 'Something bad in pdf content: ' + error);
}
let filepath = path.join(__dirname, '../REST/uploads/', filename);
let result = pdfDoc.pipe(fs.createWriteStream(filepath));
pdfDoc.end();
return new Promise(resolve =>
{
result.on('finish', resolve);
})
})
Problem occured when I want test
result.on('finish',resolve);
This is my test:
let pdfGeneratorMock = sinon.stub();
let endMock = sinon.stub().callsFake(function ()
{
return 0;
});
let pipeMock = sinon.spy();
let createPdfKitDocumentMock = sinon.spy(() =>
{
return {
end: endMock,
pipe: pipeMock
}
});
let pdfMakePrinterMock = sinon.spy(function ()
{
return {
createPdfKitDocument: createPdfKitDocumentMock
}
});
let onMock = sinon.spy(function(text,callback){
return callback();
});
let writeStreamMock = sinon.spy(() =>
{
return {
on: onMock
}
});
let fs = {
mkdirSync: sinon.spy(),
createWriteStream: writeStreamMock
};
........
it('should call createPefKitDocument', function ()
{
expect(createPdfKitDocumentMock).callCount(1);
});
it('should call fs.createWriteStream', function ()
{
expect(writeStreamMock).callCount(1);
});
it('should call pipe', function ()
{
expect(pipeMock).callCount(1);
});
it('should call end', function ()
{
expect(endMock).callCount(1);
});
it('should call on', function ()
{
expect(onMock).callCount(1);
});
Test not pass to onMock call and I don't have idea how mock this event and resolves to next then.

I resolved my problem with using yields. Change pipeMock to stub:
let pipeMock = sinon.stub();
In before() pipeMock return yields:
pipeMock.returns({ on: sinon.stub().yields()});
and now test call calback and resolve promise

Related

Sinon/sandbox test says that function was never called

I want to write a unit test that checks to see if a function was called, but i'm getting the error:
submitDetails
submitDetails
sendEmail:
AssertionError: expected sendEmail to have been called exactly once, but it was called 0 times
From what I can see my function submitDetails.submitDetails clearly runs the function sendEmail.sendEmail but it's saying that it's never called. I've also tried just using 'spy.called' instead of calledOnce but I get the same result.
Test file:
const submitDetails = require('../src/scripts/submitDetails')
const sendEmail = require('../src/lib/sendEmail')
describe('submitDetails', function () {
let sandbox = null
before(() => {
sandbox = sinon.createSandbox()
})
afterEach(() => {
sandbox.restore()
})
describe('submitDetails', () => {
let mockParams, result
beforeEach(async () => {
sandbox.spy(sendEmail, 'sendEmail')
})
it('sendEmail', () => {
expect(sendEmail.sendEmail).to.have.been.calledOnce()
})
})
})
SubmitDetails.js (file that's being test)
const { sendEmail } = require('../lib/sendEmail')
const submitDetails = {}
submitDetails.submitDetails = query => {
return sendEmail(query)
}
module.exports = submitDetails
You didn't call submitDetails.submitDetails() method in your test case. Here is the working example:
sendEmail.ts:
module.exports = {
sendEmail() {}
};
submitDetails.ts:
const sendEmail = require('./sendEmail');
// #ts-ignore
const submitDetails = {};
// #ts-ignore
submitDetails.submitDetails = query => {
return sendEmail.sendEmail(query);
};
module.exports = submitDetails;
submitDetails.spec.ts:
import { expect } from 'chai';
import sinon, { SinonSandbox, SinonSpy } from 'sinon';
const submitDetails = require('./submitDetails');
const sendEmail = require('./sendEmail');
describe('submitDetails', () => {
let sandbox: SinonSandbox;
before(() => {
sandbox = sinon.createSandbox();
});
afterEach(() => {
sandbox.restore();
});
describe('submitDetails', () => {
let sendEmailSpy: SinonSpy;
beforeEach(() => {
sendEmailSpy = sandbox.spy(sendEmail, 'sendEmail');
});
it('sendEmail', () => {
submitDetails.submitDetails();
sandbox.assert.calledOnce(sendEmailSpy);
expect(sendEmailSpy.calledOnce).to.be.true;
});
});
});
Unit test result:
submitDetails
submitDetails
✓ sendEmail
1 passing (22ms)
Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/58058653

I cannot implement an async function

I've started working with protractor-cucumber automation testing (https://github.com/mlev/protractor-cucumber-example), previously in one of my other projects I had no issue implementing async await functions, however, in this case I cannot.
This is my current semi-working (protractor outpust completed for all tasks, however it will not wait at browser.sleep) code:
I have tried nodes async await libary and the following code:
this.get = async function someName(){
await browser.get('https://translate.google.com/');
};
this.Given('The Translate is open', async function (callback) {
await this.page.get();
callback();
}
StepsDef:
var chai = require('chai').use(require('chai-as-promised'));
var expect = chai.expect;
var TranslateSteps = function() {
var TranslatePage = require("../pages/translate_page");
this.World = function MyWorld() {
this.page = new TranslatePage();
};
this.Given('The Translate is open', function (callback) {
this.page.get();
callback();
}
)
this.Then('I wait $string seconds', function (string) {
browser.sleep(string * 10000)
}
};
module.exports = TranslateSteps;
Page:
var TranslatePage = function() {
this.get = function (){
browser.get('https://translate.google.com/');
};
this.setInputBox = function (value) {
element(by.className("gt-hl-layer")).sendKeys(value)
console.log("setInput")
};
this.clickLang = function () {
element(by.className("sl-more tlid-open-source-language-list")).click()
console.log("clickLang")
}
};
module.exports = TranslatePage;
most of the time I got error code 1 or 100, at times i got no 199.
Firstly make sure that you disable promise manager by adding this SELENIUM_PROMISE_MANAGER: false line in the protractor.conf.js file.
You don't need to use the callback function.
this.get = async function() {
await browser.get('https://translate.google.com/');
};
this.Given('The Translate is open', async function() {
await this.page.get();
});
As I said above you don't need the callback function. Alson the sleep method expects number type instead of the string.
var TranslateSteps = function() {
var TranslatePage = require("../pages/translate_page");
this.World = function MyWorld() {
this.page = new TranslatePage();
};
this.Given('The Translate is open', async function() {
await this.page.get();
});
this.Then('I wait {num} seconds', async function(num) {
await browser.sleep(num * 10000)
});
};
Add async/await's.
var TranslatePage = function() {
this.get = async function() {
await browser.get('https://translate.google.com/');
};
this.setInputBox = async function(value) {
await element(by.className("gt-hl-layer")).sendKeys(value)
await console.log("setInput")
};
this.clickLang = async function() {
await element(by.className("sl-more tlid-open-source-language-list")).click()
await console.log("clickLang")
}
};
module.exports = TranslatePage;
this.When('I enter $string', async function myF(string) {
await this.page.setFirstValue(string);
return true;
});
and:
this.setFirstValue = async function asd(value) {
await element(by.className('orig tlid-source-text-input goog-textarea')).sendKeys(value);
};
works like a charm

nodejs unit test undefined after required controller

I am try to make a unit test for a controller in a project that use nodeJS, but when I call a function of a controller the test return that this controller is undefined.
This is my MK.js code:
MK = {}
MK.deleteAgent() {
}
module.exports = MK
My test code MK.spec.js:
const assert = require("assert");
const sinon = require("sinon");
const { MK } = require("./MK");
describe("MK controllers", function () {
let rt_model;
beforeEach(function () {
rt_model = {
findAll: sinon.fake.resolves()
}
});
describe("deleteAgent", function () {
it("should call rt_model.findAll", function (done) {
// a mock for the Web response
const response = {
status: () => null,
json: () => {
assert.strictEqual(rt_model.findAll.callCount, 1);
done();
}
};
MK.deleteAgent(null, response);
});
});
afterEach(() => {
// Restore the default sandbox here
sinon.restore();
});
});
But ther result that I get when run test is that MK is undefined

How to stub oracledb with sinon?

Here is my function which will return a promise once it gets data from oracle database:
const getDataFromOracleDB = (filter, query) =>
new Promise(async (resolve, reject) => {
let conn;
try {
conn = await oracledb.getConnection(dbConfig);
const result = await conn.execute(query, [filter]);
const { rows } = result;
...
catch (err) {
...
}
};
As the unit test, I want to stub conn.execute, but have no idea how to do that. I've treid:
const stub = sinon.stub(conn, 'execute').returns([1, 2, 3]);
But got:
TypeError: Cannot stub non-existent own property execute
Any suggestions?
I can't replicate the error with the code you supplied, but perhaps this quick mockup will help:
const chai = require('chai');
const sinon = require('sinon');
const oracledb = require('oracledb');
const config = require('./dbConfig.js');
const expect = chai.expect;
sinon.stub(oracledb, 'getConnection').resolves({
execute: function() {},
close: function() {}
});
describe('Parent', () => {
describe('child', () => {
it('should work', async (done) => {
let conn;
try {
conn = await oracledb.getConnection(config);
sinon.stub(conn, 'execute').resolves({
rows: [[2]]
});
let result = await conn.execute(
'select 1 from dual'
);
expect(result.rows[0][0]).to.equal(2);
done();
} catch (err) {
done(err);
} finally {
if (conn) {
try {
await conn.close();
} catch (err) {
console.error(err);
}
}
}
});
});
});
The query would normally return a value of 1, but this returns 2 and passes.

proxyquire not finding module

I have the following code which I am trying to test. However proxyquire cannot find the readDirectory.js. Does anyone understand why?
It's returning the following error, Error: Cannot find module '../readDirectory.js' and point to the line were testedModule = proxyquire('../readDirectory.js', {
readDirectory.js:
var dir = require('node-dir');
var _getFiles = {};
_getFiles._get = function (directory, callback) {
dir.readFiles(directory,
function(err, content, next) {
if (err) throw err;
console.log('content:', content);
});
};
module.exports = _getFiles;
tests:
var mockDir = require('mock-fs');
describe("readDirectory", function () {
var testedModule, callbackSpy, readFileStub;
before(function () {
mockDir({
tmp: {
images: {
thumb_test: "thumbnail pic",
small_test: "small pic",
medium_test: "medium pic"
}
}
});
readFileStub = sinon.stub();
callbackSpy = sinon.spy();
testedModule = proxyquire('../readDirectory.js', {
"node-dir": {
"readFiles": readFileStub
}
});
});
after(function () {
mockDir.restore();
});
it("call readdir with fake directory", function () {
testedModule._get(mockDir, function () {console.log("Hello");});
});
});

Resources