Mocking database when testing microservice functions
I have created a basic NodeJS micro-service with pg-promise. I have created the routing file (index.js) containing the APIs via express:
var express = require('express');
var router = express.Router();
var db = require('./../queries');
router.get('/api/puppy', db.getAllPuppies);
router.post('/api/puppy', db.createPuppy);
module.exports = router;
I have then added the two functions in the queries.js file:
var promise = require('bluebird');
var options = {
promiseLib: promise
};
var config = require('./config.json');
var pgp = require('pg-promise')(options);
var connectionString = process.env.DB_PATH || "postgres://postgres:xxxx@localhost:5432/postgres";
var db = pgp(connectionString);
function getAllPuppies(req, res, next) {
db.any('select * from puppy')
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
});
})
.catch(function (err) {
return next(err);
});
}
function createPuppy(req, res, next) {
db.none('insert into ' +
'puppy(name, description) ' +
'values(${name}, ${description})',
req.body)
.then(function () {
res.status(200)
.json({
status: 'success',
});
})
.catch(function (err) {
return next(err);
});
}
module.exports = {
getAllPuppies,
createPuppy,
};
The application works perfectly. I would like to test now these two functions in one way or another, but I am a bit stuck in the way the database should be mocked (I am using Mocha and functions such as beforeEach) to retrieve or create data.
javascript node.js database postgresql pg-promise
add a comment |
I have created a basic NodeJS micro-service with pg-promise. I have created the routing file (index.js) containing the APIs via express:
var express = require('express');
var router = express.Router();
var db = require('./../queries');
router.get('/api/puppy', db.getAllPuppies);
router.post('/api/puppy', db.createPuppy);
module.exports = router;
I have then added the two functions in the queries.js file:
var promise = require('bluebird');
var options = {
promiseLib: promise
};
var config = require('./config.json');
var pgp = require('pg-promise')(options);
var connectionString = process.env.DB_PATH || "postgres://postgres:xxxx@localhost:5432/postgres";
var db = pgp(connectionString);
function getAllPuppies(req, res, next) {
db.any('select * from puppy')
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
});
})
.catch(function (err) {
return next(err);
});
}
function createPuppy(req, res, next) {
db.none('insert into ' +
'puppy(name, description) ' +
'values(${name}, ${description})',
req.body)
.then(function () {
res.status(200)
.json({
status: 'success',
});
})
.catch(function (err) {
return next(err);
});
}
module.exports = {
getAllPuppies,
createPuppy,
};
The application works perfectly. I would like to test now these two functions in one way or another, but I am a bit stuck in the way the database should be mocked (I am using Mocha and functions such as beforeEach) to retrieve or create data.
javascript node.js database postgresql pg-promise
1
An example: coderwall.com/p/axugwa/…
– vitaly-t
May 26 '17 at 14:43
Thanks Vitaly, in the example the queries are tested, but not the actual functions however.
– Anto
May 26 '17 at 15:56
Oh, there's plenty of that in well-written tutorials: blog.jscrambler.com/testing-apis-mocha-2
– vitaly-t
May 26 '17 at 16:18
Hi Vitaly, many thanks for that. I have tried the tutorial, but this uses lowdb and a json file. I have tried to use these examples and modify them for my purpose, but at no avail, I am pretty frustrated.
– Anto
May 26 '17 at 19:12
The database is completely irrelevant to API testing. You are only testing requests + responses, not what's inside the handlers.
– vitaly-t
May 26 '17 at 21:22
add a comment |
I have created a basic NodeJS micro-service with pg-promise. I have created the routing file (index.js) containing the APIs via express:
var express = require('express');
var router = express.Router();
var db = require('./../queries');
router.get('/api/puppy', db.getAllPuppies);
router.post('/api/puppy', db.createPuppy);
module.exports = router;
I have then added the two functions in the queries.js file:
var promise = require('bluebird');
var options = {
promiseLib: promise
};
var config = require('./config.json');
var pgp = require('pg-promise')(options);
var connectionString = process.env.DB_PATH || "postgres://postgres:xxxx@localhost:5432/postgres";
var db = pgp(connectionString);
function getAllPuppies(req, res, next) {
db.any('select * from puppy')
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
});
})
.catch(function (err) {
return next(err);
});
}
function createPuppy(req, res, next) {
db.none('insert into ' +
'puppy(name, description) ' +
'values(${name}, ${description})',
req.body)
.then(function () {
res.status(200)
.json({
status: 'success',
});
})
.catch(function (err) {
return next(err);
});
}
module.exports = {
getAllPuppies,
createPuppy,
};
The application works perfectly. I would like to test now these two functions in one way or another, but I am a bit stuck in the way the database should be mocked (I am using Mocha and functions such as beforeEach) to retrieve or create data.
javascript node.js database postgresql pg-promise
I have created a basic NodeJS micro-service with pg-promise. I have created the routing file (index.js) containing the APIs via express:
var express = require('express');
var router = express.Router();
var db = require('./../queries');
router.get('/api/puppy', db.getAllPuppies);
router.post('/api/puppy', db.createPuppy);
module.exports = router;
I have then added the two functions in the queries.js file:
var promise = require('bluebird');
var options = {
promiseLib: promise
};
var config = require('./config.json');
var pgp = require('pg-promise')(options);
var connectionString = process.env.DB_PATH || "postgres://postgres:xxxx@localhost:5432/postgres";
var db = pgp(connectionString);
function getAllPuppies(req, res, next) {
db.any('select * from puppy')
.then(function (data) {
res.status(200)
.json({
status: 'success',
data: data,
});
})
.catch(function (err) {
return next(err);
});
}
function createPuppy(req, res, next) {
db.none('insert into ' +
'puppy(name, description) ' +
'values(${name}, ${description})',
req.body)
.then(function () {
res.status(200)
.json({
status: 'success',
});
})
.catch(function (err) {
return next(err);
});
}
module.exports = {
getAllPuppies,
createPuppy,
};
The application works perfectly. I would like to test now these two functions in one way or another, but I am a bit stuck in the way the database should be mocked (I am using Mocha and functions such as beforeEach) to retrieve or create data.
javascript node.js database postgresql pg-promise
javascript node.js database postgresql pg-promise
edited Jun 22 '18 at 22:02
halfer
14.7k759116
14.7k759116
asked May 26 '17 at 10:25
AntoAnto
2,290125697
2,290125697
1
An example: coderwall.com/p/axugwa/…
– vitaly-t
May 26 '17 at 14:43
Thanks Vitaly, in the example the queries are tested, but not the actual functions however.
– Anto
May 26 '17 at 15:56
Oh, there's plenty of that in well-written tutorials: blog.jscrambler.com/testing-apis-mocha-2
– vitaly-t
May 26 '17 at 16:18
Hi Vitaly, many thanks for that. I have tried the tutorial, but this uses lowdb and a json file. I have tried to use these examples and modify them for my purpose, but at no avail, I am pretty frustrated.
– Anto
May 26 '17 at 19:12
The database is completely irrelevant to API testing. You are only testing requests + responses, not what's inside the handlers.
– vitaly-t
May 26 '17 at 21:22
add a comment |
1
An example: coderwall.com/p/axugwa/…
– vitaly-t
May 26 '17 at 14:43
Thanks Vitaly, in the example the queries are tested, but not the actual functions however.
– Anto
May 26 '17 at 15:56
Oh, there's plenty of that in well-written tutorials: blog.jscrambler.com/testing-apis-mocha-2
– vitaly-t
May 26 '17 at 16:18
Hi Vitaly, many thanks for that. I have tried the tutorial, but this uses lowdb and a json file. I have tried to use these examples and modify them for my purpose, but at no avail, I am pretty frustrated.
– Anto
May 26 '17 at 19:12
The database is completely irrelevant to API testing. You are only testing requests + responses, not what's inside the handlers.
– vitaly-t
May 26 '17 at 21:22
1
1
An example: coderwall.com/p/axugwa/…
– vitaly-t
May 26 '17 at 14:43
An example: coderwall.com/p/axugwa/…
– vitaly-t
May 26 '17 at 14:43
Thanks Vitaly, in the example the queries are tested, but not the actual functions however.
– Anto
May 26 '17 at 15:56
Thanks Vitaly, in the example the queries are tested, but not the actual functions however.
– Anto
May 26 '17 at 15:56
Oh, there's plenty of that in well-written tutorials: blog.jscrambler.com/testing-apis-mocha-2
– vitaly-t
May 26 '17 at 16:18
Oh, there's plenty of that in well-written tutorials: blog.jscrambler.com/testing-apis-mocha-2
– vitaly-t
May 26 '17 at 16:18
Hi Vitaly, many thanks for that. I have tried the tutorial, but this uses lowdb and a json file. I have tried to use these examples and modify them for my purpose, but at no avail, I am pretty frustrated.
– Anto
May 26 '17 at 19:12
Hi Vitaly, many thanks for that. I have tried the tutorial, but this uses lowdb and a json file. I have tried to use these examples and modify them for my purpose, but at no avail, I am pretty frustrated.
– Anto
May 26 '17 at 19:12
The database is completely irrelevant to API testing. You are only testing requests + responses, not what's inside the handlers.
– vitaly-t
May 26 '17 at 21:22
The database is completely irrelevant to API testing. You are only testing requests + responses, not what's inside the handlers.
– vitaly-t
May 26 '17 at 21:22
add a comment |
2 Answers
2
active
oldest
votes
As a general rule of thumb you have two options:
- Use dependency injection and send in a mock database service
- Configure your testing environment to use a test database so that you can use your database as is.
Either is a potentially helpful test. The first option would be more of a unit test, and requires that you refactor your code to make use of dependency injection. Then, your test code would inject in some kind of mock object that would have the same API as your actual database object. If you're new to this sort of thing, google will be your friend: unit testing and inversion of control are fairly straight-forward conceptually, but there can be lots of details to get stuck in.
Since you aren't already setup with dependency injection the next thing you could do is configure your testing environment to work with some kind of test databases. This would make it more of an integration test. You could do that by setting up a different database for your tests, and then you would (still) have to refactor your code to adjust your database connection credentials based on your environment. Again, it is conceptually simple but there can be lots of details to get lost in.
If you are new to code testing it is worth spending some time reading about it and really understanding how it works. Read up on the topics of inversion of control and unit testing. Proper code testing is a huge benefit to just about any code base, but you really have to plan for it from the beginning, as proper inversion of control (which is necessary for proper code testing) does require organizing your code in a different way.
Edited to add some specifics:
Code testing can be very easy once you plan for it and do it, but getting started is not a small task. The most important issue is that your code has to be written in such a way as to actually plan for future code testing. In your case that means either refactoring your code to work with actual dependency injection (which node.js supports) or at least adjusting your database connection based on environment. The latter would be much easier to do, but it would only allow for limited tests. In the end if you want to do proper code testing you will have to refactor for dependency injection/inversion of control.
Once you do that your next step will be to select a testing framework. I don't know off the top of my head what the default is for node.js, but most languages/frameworks have a fairly standard one that shouldn't be hard to find. There will probably be more than one option to, so you might spend some time selecting one that fits your style best. Once you choose your testing framework, you will have to read up on how it works, how to set it up, and how to use it.
Once you get those things done you can actually start testing. It's a lot of work the first time you do it, but it is 100% worth the effort.
thanks a lot. I am thinking to use Mocha as testing framework. Would it please be possible to have a small example? I have had a look on Internet but I am getting pretty confused by the different types of examples.
– Anto
May 26 '17 at 14:10
1
I'm afraid I can't help there, as I'm not a node.js person. Hopefully someone else will come by with more specifics, or you could try asking again with more detailed questions as you work through getting mocha setup and running. The best place to get started is to just get anything tested: even just a very simple assertion:expect('test').to.be.a('string');
– Conor Mancone
May 26 '17 at 14:24
add a comment |
There's a couple of problems with some things you're doing that are going to make testing this in the long run a REAL problem. However let's approach the biggest offender: Declaring your database in your route file. This is a BIG no-no and it should only ever be declared once and required where needed. A great example can be found by the author of pg-promise
here at the official demo. The big thing to pay attention to is compartmentalization. If you don't design correctly, testing is a PITA which you're running into right now. However if you compartmentalize it correctly, when you write your tests you can just pass it mock objects with methods for it to call that will give you a testable environment.
Biggest example from the demo:
var options = {
// Use a custom promise library, instead of the default ES6 Promise:
promiseLib: promise,
// Extending the database protocol with our custom repositories:
extend: obj => {
// Do not use 'require()' here, because this event occurs for every task
// and transaction being executed, which should be as fast as possible.
obj.users = repos.users(obj, pgp);
obj.products = repos.products(obj, pgp);
// Alternatively, you can set all repositories in a loop:
//
// for (var r in repos) {
// obj[r] = repos[r](obj, pgp);
// }
}
};
With this you can now write easy mocks in Mocha(I'd suggest looking at unitjs for some example, but this way when you pass something to a test you also just need to pass a req
object with an app
object with a pgp
object with a db
.... you get the idea.
So the big takeaway here is that you're designing wrong(your code looks fine). You need to refactor things into separate parts so when you do your tests you can actually write meaningful tests.
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%2f44199201%2fmocking-database-when-testing-microservice-functions%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
As a general rule of thumb you have two options:
- Use dependency injection and send in a mock database service
- Configure your testing environment to use a test database so that you can use your database as is.
Either is a potentially helpful test. The first option would be more of a unit test, and requires that you refactor your code to make use of dependency injection. Then, your test code would inject in some kind of mock object that would have the same API as your actual database object. If you're new to this sort of thing, google will be your friend: unit testing and inversion of control are fairly straight-forward conceptually, but there can be lots of details to get stuck in.
Since you aren't already setup with dependency injection the next thing you could do is configure your testing environment to work with some kind of test databases. This would make it more of an integration test. You could do that by setting up a different database for your tests, and then you would (still) have to refactor your code to adjust your database connection credentials based on your environment. Again, it is conceptually simple but there can be lots of details to get lost in.
If you are new to code testing it is worth spending some time reading about it and really understanding how it works. Read up on the topics of inversion of control and unit testing. Proper code testing is a huge benefit to just about any code base, but you really have to plan for it from the beginning, as proper inversion of control (which is necessary for proper code testing) does require organizing your code in a different way.
Edited to add some specifics:
Code testing can be very easy once you plan for it and do it, but getting started is not a small task. The most important issue is that your code has to be written in such a way as to actually plan for future code testing. In your case that means either refactoring your code to work with actual dependency injection (which node.js supports) or at least adjusting your database connection based on environment. The latter would be much easier to do, but it would only allow for limited tests. In the end if you want to do proper code testing you will have to refactor for dependency injection/inversion of control.
Once you do that your next step will be to select a testing framework. I don't know off the top of my head what the default is for node.js, but most languages/frameworks have a fairly standard one that shouldn't be hard to find. There will probably be more than one option to, so you might spend some time selecting one that fits your style best. Once you choose your testing framework, you will have to read up on how it works, how to set it up, and how to use it.
Once you get those things done you can actually start testing. It's a lot of work the first time you do it, but it is 100% worth the effort.
thanks a lot. I am thinking to use Mocha as testing framework. Would it please be possible to have a small example? I have had a look on Internet but I am getting pretty confused by the different types of examples.
– Anto
May 26 '17 at 14:10
1
I'm afraid I can't help there, as I'm not a node.js person. Hopefully someone else will come by with more specifics, or you could try asking again with more detailed questions as you work through getting mocha setup and running. The best place to get started is to just get anything tested: even just a very simple assertion:expect('test').to.be.a('string');
– Conor Mancone
May 26 '17 at 14:24
add a comment |
As a general rule of thumb you have two options:
- Use dependency injection and send in a mock database service
- Configure your testing environment to use a test database so that you can use your database as is.
Either is a potentially helpful test. The first option would be more of a unit test, and requires that you refactor your code to make use of dependency injection. Then, your test code would inject in some kind of mock object that would have the same API as your actual database object. If you're new to this sort of thing, google will be your friend: unit testing and inversion of control are fairly straight-forward conceptually, but there can be lots of details to get stuck in.
Since you aren't already setup with dependency injection the next thing you could do is configure your testing environment to work with some kind of test databases. This would make it more of an integration test. You could do that by setting up a different database for your tests, and then you would (still) have to refactor your code to adjust your database connection credentials based on your environment. Again, it is conceptually simple but there can be lots of details to get lost in.
If you are new to code testing it is worth spending some time reading about it and really understanding how it works. Read up on the topics of inversion of control and unit testing. Proper code testing is a huge benefit to just about any code base, but you really have to plan for it from the beginning, as proper inversion of control (which is necessary for proper code testing) does require organizing your code in a different way.
Edited to add some specifics:
Code testing can be very easy once you plan for it and do it, but getting started is not a small task. The most important issue is that your code has to be written in such a way as to actually plan for future code testing. In your case that means either refactoring your code to work with actual dependency injection (which node.js supports) or at least adjusting your database connection based on environment. The latter would be much easier to do, but it would only allow for limited tests. In the end if you want to do proper code testing you will have to refactor for dependency injection/inversion of control.
Once you do that your next step will be to select a testing framework. I don't know off the top of my head what the default is for node.js, but most languages/frameworks have a fairly standard one that shouldn't be hard to find. There will probably be more than one option to, so you might spend some time selecting one that fits your style best. Once you choose your testing framework, you will have to read up on how it works, how to set it up, and how to use it.
Once you get those things done you can actually start testing. It's a lot of work the first time you do it, but it is 100% worth the effort.
thanks a lot. I am thinking to use Mocha as testing framework. Would it please be possible to have a small example? I have had a look on Internet but I am getting pretty confused by the different types of examples.
– Anto
May 26 '17 at 14:10
1
I'm afraid I can't help there, as I'm not a node.js person. Hopefully someone else will come by with more specifics, or you could try asking again with more detailed questions as you work through getting mocha setup and running. The best place to get started is to just get anything tested: even just a very simple assertion:expect('test').to.be.a('string');
– Conor Mancone
May 26 '17 at 14:24
add a comment |
As a general rule of thumb you have two options:
- Use dependency injection and send in a mock database service
- Configure your testing environment to use a test database so that you can use your database as is.
Either is a potentially helpful test. The first option would be more of a unit test, and requires that you refactor your code to make use of dependency injection. Then, your test code would inject in some kind of mock object that would have the same API as your actual database object. If you're new to this sort of thing, google will be your friend: unit testing and inversion of control are fairly straight-forward conceptually, but there can be lots of details to get stuck in.
Since you aren't already setup with dependency injection the next thing you could do is configure your testing environment to work with some kind of test databases. This would make it more of an integration test. You could do that by setting up a different database for your tests, and then you would (still) have to refactor your code to adjust your database connection credentials based on your environment. Again, it is conceptually simple but there can be lots of details to get lost in.
If you are new to code testing it is worth spending some time reading about it and really understanding how it works. Read up on the topics of inversion of control and unit testing. Proper code testing is a huge benefit to just about any code base, but you really have to plan for it from the beginning, as proper inversion of control (which is necessary for proper code testing) does require organizing your code in a different way.
Edited to add some specifics:
Code testing can be very easy once you plan for it and do it, but getting started is not a small task. The most important issue is that your code has to be written in such a way as to actually plan for future code testing. In your case that means either refactoring your code to work with actual dependency injection (which node.js supports) or at least adjusting your database connection based on environment. The latter would be much easier to do, but it would only allow for limited tests. In the end if you want to do proper code testing you will have to refactor for dependency injection/inversion of control.
Once you do that your next step will be to select a testing framework. I don't know off the top of my head what the default is for node.js, but most languages/frameworks have a fairly standard one that shouldn't be hard to find. There will probably be more than one option to, so you might spend some time selecting one that fits your style best. Once you choose your testing framework, you will have to read up on how it works, how to set it up, and how to use it.
Once you get those things done you can actually start testing. It's a lot of work the first time you do it, but it is 100% worth the effort.
As a general rule of thumb you have two options:
- Use dependency injection and send in a mock database service
- Configure your testing environment to use a test database so that you can use your database as is.
Either is a potentially helpful test. The first option would be more of a unit test, and requires that you refactor your code to make use of dependency injection. Then, your test code would inject in some kind of mock object that would have the same API as your actual database object. If you're new to this sort of thing, google will be your friend: unit testing and inversion of control are fairly straight-forward conceptually, but there can be lots of details to get stuck in.
Since you aren't already setup with dependency injection the next thing you could do is configure your testing environment to work with some kind of test databases. This would make it more of an integration test. You could do that by setting up a different database for your tests, and then you would (still) have to refactor your code to adjust your database connection credentials based on your environment. Again, it is conceptually simple but there can be lots of details to get lost in.
If you are new to code testing it is worth spending some time reading about it and really understanding how it works. Read up on the topics of inversion of control and unit testing. Proper code testing is a huge benefit to just about any code base, but you really have to plan for it from the beginning, as proper inversion of control (which is necessary for proper code testing) does require organizing your code in a different way.
Edited to add some specifics:
Code testing can be very easy once you plan for it and do it, but getting started is not a small task. The most important issue is that your code has to be written in such a way as to actually plan for future code testing. In your case that means either refactoring your code to work with actual dependency injection (which node.js supports) or at least adjusting your database connection based on environment. The latter would be much easier to do, but it would only allow for limited tests. In the end if you want to do proper code testing you will have to refactor for dependency injection/inversion of control.
Once you do that your next step will be to select a testing framework. I don't know off the top of my head what the default is for node.js, but most languages/frameworks have a fairly standard one that shouldn't be hard to find. There will probably be more than one option to, so you might spend some time selecting one that fits your style best. Once you choose your testing framework, you will have to read up on how it works, how to set it up, and how to use it.
Once you get those things done you can actually start testing. It's a lot of work the first time you do it, but it is 100% worth the effort.
edited May 26 '17 at 13:40
answered May 26 '17 at 13:29
Conor ManconeConor Mancone
1,4331120
1,4331120
thanks a lot. I am thinking to use Mocha as testing framework. Would it please be possible to have a small example? I have had a look on Internet but I am getting pretty confused by the different types of examples.
– Anto
May 26 '17 at 14:10
1
I'm afraid I can't help there, as I'm not a node.js person. Hopefully someone else will come by with more specifics, or you could try asking again with more detailed questions as you work through getting mocha setup and running. The best place to get started is to just get anything tested: even just a very simple assertion:expect('test').to.be.a('string');
– Conor Mancone
May 26 '17 at 14:24
add a comment |
thanks a lot. I am thinking to use Mocha as testing framework. Would it please be possible to have a small example? I have had a look on Internet but I am getting pretty confused by the different types of examples.
– Anto
May 26 '17 at 14:10
1
I'm afraid I can't help there, as I'm not a node.js person. Hopefully someone else will come by with more specifics, or you could try asking again with more detailed questions as you work through getting mocha setup and running. The best place to get started is to just get anything tested: even just a very simple assertion:expect('test').to.be.a('string');
– Conor Mancone
May 26 '17 at 14:24
thanks a lot. I am thinking to use Mocha as testing framework. Would it please be possible to have a small example? I have had a look on Internet but I am getting pretty confused by the different types of examples.
– Anto
May 26 '17 at 14:10
thanks a lot. I am thinking to use Mocha as testing framework. Would it please be possible to have a small example? I have had a look on Internet but I am getting pretty confused by the different types of examples.
– Anto
May 26 '17 at 14:10
1
1
I'm afraid I can't help there, as I'm not a node.js person. Hopefully someone else will come by with more specifics, or you could try asking again with more detailed questions as you work through getting mocha setup and running. The best place to get started is to just get anything tested: even just a very simple assertion:
expect('test').to.be.a('string');
– Conor Mancone
May 26 '17 at 14:24
I'm afraid I can't help there, as I'm not a node.js person. Hopefully someone else will come by with more specifics, or you could try asking again with more detailed questions as you work through getting mocha setup and running. The best place to get started is to just get anything tested: even just a very simple assertion:
expect('test').to.be.a('string');
– Conor Mancone
May 26 '17 at 14:24
add a comment |
There's a couple of problems with some things you're doing that are going to make testing this in the long run a REAL problem. However let's approach the biggest offender: Declaring your database in your route file. This is a BIG no-no and it should only ever be declared once and required where needed. A great example can be found by the author of pg-promise
here at the official demo. The big thing to pay attention to is compartmentalization. If you don't design correctly, testing is a PITA which you're running into right now. However if you compartmentalize it correctly, when you write your tests you can just pass it mock objects with methods for it to call that will give you a testable environment.
Biggest example from the demo:
var options = {
// Use a custom promise library, instead of the default ES6 Promise:
promiseLib: promise,
// Extending the database protocol with our custom repositories:
extend: obj => {
// Do not use 'require()' here, because this event occurs for every task
// and transaction being executed, which should be as fast as possible.
obj.users = repos.users(obj, pgp);
obj.products = repos.products(obj, pgp);
// Alternatively, you can set all repositories in a loop:
//
// for (var r in repos) {
// obj[r] = repos[r](obj, pgp);
// }
}
};
With this you can now write easy mocks in Mocha(I'd suggest looking at unitjs for some example, but this way when you pass something to a test you also just need to pass a req
object with an app
object with a pgp
object with a db
.... you get the idea.
So the big takeaway here is that you're designing wrong(your code looks fine). You need to refactor things into separate parts so when you do your tests you can actually write meaningful tests.
add a comment |
There's a couple of problems with some things you're doing that are going to make testing this in the long run a REAL problem. However let's approach the biggest offender: Declaring your database in your route file. This is a BIG no-no and it should only ever be declared once and required where needed. A great example can be found by the author of pg-promise
here at the official demo. The big thing to pay attention to is compartmentalization. If you don't design correctly, testing is a PITA which you're running into right now. However if you compartmentalize it correctly, when you write your tests you can just pass it mock objects with methods for it to call that will give you a testable environment.
Biggest example from the demo:
var options = {
// Use a custom promise library, instead of the default ES6 Promise:
promiseLib: promise,
// Extending the database protocol with our custom repositories:
extend: obj => {
// Do not use 'require()' here, because this event occurs for every task
// and transaction being executed, which should be as fast as possible.
obj.users = repos.users(obj, pgp);
obj.products = repos.products(obj, pgp);
// Alternatively, you can set all repositories in a loop:
//
// for (var r in repos) {
// obj[r] = repos[r](obj, pgp);
// }
}
};
With this you can now write easy mocks in Mocha(I'd suggest looking at unitjs for some example, but this way when you pass something to a test you also just need to pass a req
object with an app
object with a pgp
object with a db
.... you get the idea.
So the big takeaway here is that you're designing wrong(your code looks fine). You need to refactor things into separate parts so when you do your tests you can actually write meaningful tests.
add a comment |
There's a couple of problems with some things you're doing that are going to make testing this in the long run a REAL problem. However let's approach the biggest offender: Declaring your database in your route file. This is a BIG no-no and it should only ever be declared once and required where needed. A great example can be found by the author of pg-promise
here at the official demo. The big thing to pay attention to is compartmentalization. If you don't design correctly, testing is a PITA which you're running into right now. However if you compartmentalize it correctly, when you write your tests you can just pass it mock objects with methods for it to call that will give you a testable environment.
Biggest example from the demo:
var options = {
// Use a custom promise library, instead of the default ES6 Promise:
promiseLib: promise,
// Extending the database protocol with our custom repositories:
extend: obj => {
// Do not use 'require()' here, because this event occurs for every task
// and transaction being executed, which should be as fast as possible.
obj.users = repos.users(obj, pgp);
obj.products = repos.products(obj, pgp);
// Alternatively, you can set all repositories in a loop:
//
// for (var r in repos) {
// obj[r] = repos[r](obj, pgp);
// }
}
};
With this you can now write easy mocks in Mocha(I'd suggest looking at unitjs for some example, but this way when you pass something to a test you also just need to pass a req
object with an app
object with a pgp
object with a db
.... you get the idea.
So the big takeaway here is that you're designing wrong(your code looks fine). You need to refactor things into separate parts so when you do your tests you can actually write meaningful tests.
There's a couple of problems with some things you're doing that are going to make testing this in the long run a REAL problem. However let's approach the biggest offender: Declaring your database in your route file. This is a BIG no-no and it should only ever be declared once and required where needed. A great example can be found by the author of pg-promise
here at the official demo. The big thing to pay attention to is compartmentalization. If you don't design correctly, testing is a PITA which you're running into right now. However if you compartmentalize it correctly, when you write your tests you can just pass it mock objects with methods for it to call that will give you a testable environment.
Biggest example from the demo:
var options = {
// Use a custom promise library, instead of the default ES6 Promise:
promiseLib: promise,
// Extending the database protocol with our custom repositories:
extend: obj => {
// Do not use 'require()' here, because this event occurs for every task
// and transaction being executed, which should be as fast as possible.
obj.users = repos.users(obj, pgp);
obj.products = repos.products(obj, pgp);
// Alternatively, you can set all repositories in a loop:
//
// for (var r in repos) {
// obj[r] = repos[r](obj, pgp);
// }
}
};
With this you can now write easy mocks in Mocha(I'd suggest looking at unitjs for some example, but this way when you pass something to a test you also just need to pass a req
object with an app
object with a pgp
object with a db
.... you get the idea.
So the big takeaway here is that you're designing wrong(your code looks fine). You need to refactor things into separate parts so when you do your tests you can actually write meaningful tests.
answered May 31 '17 at 17:56
Robert MennellRobert Mennell
983517
983517
add a comment |
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.
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%2f44199201%2fmocking-database-when-testing-microservice-functions%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
1
An example: coderwall.com/p/axugwa/…
– vitaly-t
May 26 '17 at 14:43
Thanks Vitaly, in the example the queries are tested, but not the actual functions however.
– Anto
May 26 '17 at 15:56
Oh, there's plenty of that in well-written tutorials: blog.jscrambler.com/testing-apis-mocha-2
– vitaly-t
May 26 '17 at 16:18
Hi Vitaly, many thanks for that. I have tried the tutorial, but this uses lowdb and a json file. I have tried to use these examples and modify them for my purpose, but at no avail, I am pretty frustrated.
– Anto
May 26 '17 at 19:12
The database is completely irrelevant to API testing. You are only testing requests + responses, not what's inside the handlers.
– vitaly-t
May 26 '17 at 21:22