Using sinon to test a function in a promise
I am trying to test mysqlite3 data access layer but I can't seem to correctly stub my db.all() method, I am unsure if this is due to how my database is passed in or whether I am stubbing it wrong.
This is my database file:
const db = new sqlite3.Database(path.join(__dirname, '
../database/example.db'), (err) => {
if (err) return console.log(err.message)
console.log('Connected to the database')
})
module.exports.database = db
This is my function I am trying to stub:
const db = require('./database.js').database
module.exports.selectMultiple = request => {
//unimportant code
return new Promise((resolve, reject) => {
db.all(sql, (err, rows) => {
if (err)
reject(err)
else {
resolve('blah blah blah')
})
})
}
This is my attempt which I can't seem to get working:
const db = require('../../data_access/database.js').database
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.resolves([testProduct, testProduct2])
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async(done) => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({amount: 2})
expect(macbooks.length === 2).toBe(true)
expect(macbooks[0].key !== macbooks[1].key).toBe(true)
done()
})
})
If I run this the async test block times out. Does anyone know how I should be stubbing this?
Thanks!
javascript node.js jestjs sinon
add a comment |
I am trying to test mysqlite3 data access layer but I can't seem to correctly stub my db.all() method, I am unsure if this is due to how my database is passed in or whether I am stubbing it wrong.
This is my database file:
const db = new sqlite3.Database(path.join(__dirname, '
../database/example.db'), (err) => {
if (err) return console.log(err.message)
console.log('Connected to the database')
})
module.exports.database = db
This is my function I am trying to stub:
const db = require('./database.js').database
module.exports.selectMultiple = request => {
//unimportant code
return new Promise((resolve, reject) => {
db.all(sql, (err, rows) => {
if (err)
reject(err)
else {
resolve('blah blah blah')
})
})
}
This is my attempt which I can't seem to get working:
const db = require('../../data_access/database.js').database
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.resolves([testProduct, testProduct2])
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async(done) => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({amount: 2})
expect(macbooks.length === 2).toBe(true)
expect(macbooks[0].key !== macbooks[1].key).toBe(true)
done()
})
})
If I run this the async test block times out. Does anyone know how I should be stubbing this?
Thanks!
javascript node.js jestjs sinon
add a comment |
I am trying to test mysqlite3 data access layer but I can't seem to correctly stub my db.all() method, I am unsure if this is due to how my database is passed in or whether I am stubbing it wrong.
This is my database file:
const db = new sqlite3.Database(path.join(__dirname, '
../database/example.db'), (err) => {
if (err) return console.log(err.message)
console.log('Connected to the database')
})
module.exports.database = db
This is my function I am trying to stub:
const db = require('./database.js').database
module.exports.selectMultiple = request => {
//unimportant code
return new Promise((resolve, reject) => {
db.all(sql, (err, rows) => {
if (err)
reject(err)
else {
resolve('blah blah blah')
})
})
}
This is my attempt which I can't seem to get working:
const db = require('../../data_access/database.js').database
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.resolves([testProduct, testProduct2])
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async(done) => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({amount: 2})
expect(macbooks.length === 2).toBe(true)
expect(macbooks[0].key !== macbooks[1].key).toBe(true)
done()
})
})
If I run this the async test block times out. Does anyone know how I should be stubbing this?
Thanks!
javascript node.js jestjs sinon
I am trying to test mysqlite3 data access layer but I can't seem to correctly stub my db.all() method, I am unsure if this is due to how my database is passed in or whether I am stubbing it wrong.
This is my database file:
const db = new sqlite3.Database(path.join(__dirname, '
../database/example.db'), (err) => {
if (err) return console.log(err.message)
console.log('Connected to the database')
})
module.exports.database = db
This is my function I am trying to stub:
const db = require('./database.js').database
module.exports.selectMultiple = request => {
//unimportant code
return new Promise((resolve, reject) => {
db.all(sql, (err, rows) => {
if (err)
reject(err)
else {
resolve('blah blah blah')
})
})
}
This is my attempt which I can't seem to get working:
const db = require('../../data_access/database.js').database
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.resolves([testProduct, testProduct2])
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async(done) => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({amount: 2})
expect(macbooks.length === 2).toBe(true)
expect(macbooks[0].key !== macbooks[1].key).toBe(true)
done()
})
})
If I run this the async test block times out. Does anyone know how I should be stubbing this?
Thanks!
javascript node.js jestjs sinon
javascript node.js jestjs sinon
asked Nov 22 at 23:42
OultimoCoder
9119
9119
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Issue
db.all
does not return a Promise, it uses a callback as the second argument.
stub.resolves
causes the stub to return a Promise so the callback is never called and the Promise returned by selectMultiple
never resolves causing the test to timeout on await productDb.selectMultiple({ amount: 2 })
.
Solution
Stub db.all
using stub.callsArgWith
so that the callback passed as the second argument is called:
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.callsArgWith(1, null, [testProduct, testProduct2]); // use stub.callsArgWith
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async () => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({ amount: 2 })
expect(macbooks.length === 2).toBe(true) // SUCCESS
expect(macbooks[0].key !== macbooks[1].key).toBe(true) // SUCCESS
})
})
Also note that you don't need to use done
since you are using an async
test function and are using await
on the call to productDb.selectMultiple
.
1
Thank you, I understand how this works now and where I was going wrong. This answer was very helpful!
– OultimoCoder
Nov 23 at 9:12
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53439141%2fusing-sinon-to-test-a-function-in-a-promise%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Issue
db.all
does not return a Promise, it uses a callback as the second argument.
stub.resolves
causes the stub to return a Promise so the callback is never called and the Promise returned by selectMultiple
never resolves causing the test to timeout on await productDb.selectMultiple({ amount: 2 })
.
Solution
Stub db.all
using stub.callsArgWith
so that the callback passed as the second argument is called:
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.callsArgWith(1, null, [testProduct, testProduct2]); // use stub.callsArgWith
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async () => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({ amount: 2 })
expect(macbooks.length === 2).toBe(true) // SUCCESS
expect(macbooks[0].key !== macbooks[1].key).toBe(true) // SUCCESS
})
})
Also note that you don't need to use done
since you are using an async
test function and are using await
on the call to productDb.selectMultiple
.
1
Thank you, I understand how this works now and where I was going wrong. This answer was very helpful!
– OultimoCoder
Nov 23 at 9:12
add a comment |
Issue
db.all
does not return a Promise, it uses a callback as the second argument.
stub.resolves
causes the stub to return a Promise so the callback is never called and the Promise returned by selectMultiple
never resolves causing the test to timeout on await productDb.selectMultiple({ amount: 2 })
.
Solution
Stub db.all
using stub.callsArgWith
so that the callback passed as the second argument is called:
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.callsArgWith(1, null, [testProduct, testProduct2]); // use stub.callsArgWith
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async () => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({ amount: 2 })
expect(macbooks.length === 2).toBe(true) // SUCCESS
expect(macbooks[0].key !== macbooks[1].key).toBe(true) // SUCCESS
})
})
Also note that you don't need to use done
since you are using an async
test function and are using await
on the call to productDb.selectMultiple
.
1
Thank you, I understand how this works now and where I was going wrong. This answer was very helpful!
– OultimoCoder
Nov 23 at 9:12
add a comment |
Issue
db.all
does not return a Promise, it uses a callback as the second argument.
stub.resolves
causes the stub to return a Promise so the callback is never called and the Promise returned by selectMultiple
never resolves causing the test to timeout on await productDb.selectMultiple({ amount: 2 })
.
Solution
Stub db.all
using stub.callsArgWith
so that the callback passed as the second argument is called:
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.callsArgWith(1, null, [testProduct, testProduct2]); // use stub.callsArgWith
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async () => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({ amount: 2 })
expect(macbooks.length === 2).toBe(true) // SUCCESS
expect(macbooks[0].key !== macbooks[1].key).toBe(true) // SUCCESS
})
})
Also note that you don't need to use done
since you are using an async
test function and are using await
on the call to productDb.selectMultiple
.
Issue
db.all
does not return a Promise, it uses a callback as the second argument.
stub.resolves
causes the stub to return a Promise so the callback is never called and the Promise returned by selectMultiple
never resolves causing the test to timeout on await productDb.selectMultiple({ amount: 2 })
.
Solution
Stub db.all
using stub.callsArgWith
so that the callback passed as the second argument is called:
describe('select multiple', () => {
beforeEach(() => {
const testProduct2 = JSON.parse(JSON.stringify(testProduct))
testProduct2['key'] = '2'
this.multiple = sinon.stub(db, 'all')
.callsArgWith(1, null, [testProduct, testProduct2]); // use stub.callsArgWith
})
afterEach(() => {
this.multiple.restore()
})
test('select 2 products', async () => {
expect.assertions(2)
const macbooks = await productDb.selectMultiple({ amount: 2 })
expect(macbooks.length === 2).toBe(true) // SUCCESS
expect(macbooks[0].key !== macbooks[1].key).toBe(true) // SUCCESS
})
})
Also note that you don't need to use done
since you are using an async
test function and are using await
on the call to productDb.selectMultiple
.
answered Nov 23 at 3:09
brian-lives-outdoors
4,850322
4,850322
1
Thank you, I understand how this works now and where I was going wrong. This answer was very helpful!
– OultimoCoder
Nov 23 at 9:12
add a comment |
1
Thank you, I understand how this works now and where I was going wrong. This answer was very helpful!
– OultimoCoder
Nov 23 at 9:12
1
1
Thank you, I understand how this works now and where I was going wrong. This answer was very helpful!
– OultimoCoder
Nov 23 at 9:12
Thank you, I understand how this works now and where I was going wrong. This answer was very helpful!
– OultimoCoder
Nov 23 at 9:12
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53439141%2fusing-sinon-to-test-a-function-in-a-promise%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown