Is there a way to create a proxy database for server(Node.js) tests (Mocha+ Chai). DB for development and production are created on MLab. But idea create one more DB especially for the tests seems to me not so good idea.
I agree with Thilo's answer that having a dedicated DB for tests is a good idea, but you can also use something like mongo-mock for this, which is an in-memory MongoDB instance you can use for tests.
Related
I'm wondering if it is common practice to use an in-memory database for a test environment, instead of MySQL (that has to be used for development/production).
If it makes sense, how do I set this up?
I think I can create config/test.json as shown in their chat example, my app.js still requires Knex though.
Should I do something along the lines of
const knex = (NODE_ENV !== 'test') ? require('./knex') : undefined;
and then configure it only if knex !== undefined?
If I do so, all my models have to be set up twice (once for Knex, once for testing without it).
What is the right/standard way to go about this?
EDIT:
As suggested below, I use a different schema for testing.
This is done by declaring a different connection string in config/test.json.
This question is solved, thank you!
if it is common practice to use an in-memory database for a test environment, instead
Sadly it is a common practise, but not particulary good one. When you use different database for testing and other for production your tests are actually not testing that the application code is working in real database.
Other negative effect is also that you cannot use special features of any of those databases, but the code would have to use that subset of DB features, which are supported by both of the databases.
I would ran all the tests with all the supported real databases to actually make sure that code works on every targeted setup.
ps. Someone was telling to use mocks for abstracting database... that is another bad practise. They work for some small part of testing, but in general case you need to run tests against real database to be sure that code works correctly. Important thing is to setup tests in a way that you have a fast way of truncating old data and populating new test data in.
I am using ORM like Sequelize to interact with the database but I want to test the queries as unit test how can I do that without creating any fake models or instant methods like using sequelize mock.
If you don't want to mock then don't do it!
Use unit tests to test your database with the real queries - you will most likely need some "setup" and "teardown" scripts/help methods.
If you are new to unit testing, start here: https://martinfowler.com/bliki/UnitTest.html
I was wondering if there is something that I can use to mock my database. Say a function makeRelations makes relation from a certain node to another. I want to test this function but without actually making a relation in my database. Is there an easy way to do so ?
I am using expect and mocha for testing.
To access database (I don't have experience with arangodb), you typically use some driver library. You can fake that driver library calls with proxyquire.
You're testing what is likely already tested at some level.
There's some way to use more than one MongoDB database in meteor keeping reactivity/Oplog working? I've been reading about it (Post1), (Post2) and still I don't see a straighforward way to achieve this. It's possible? What's the right way? Thank you.
As you say; Default Connection isn't really an option as you can only have one DB and DDP is a bit superfluous when you only need a DB and none of the Meteor stuff. I'd think, therefore, your best approach would be to use the MongoInternals option.
The only thing missing from that option is reactivity; a method of enabling oplog tailing for these additional DB connections is mentioned in this answer. It essentially seems to be a case of passing the oplogUrl when creating the RemoteCollectionDriver, here's the example given in their answer:
var driver = new MongoInternals.RemoteCollectionDriver(
"mongodb://localhost:27017/db",
{
oplogUrl: "mongodb://localhost:27017/local"
});
var collection = new Mongo.Collection("Coll", {_driver: driver});
I'm going to write here what I've discovered until now, but I'm not going to mark the question as answered.
Concepts
What is reactivity?
Using reactivity, the data you show to your users will be updated in real time. You can enable or disable reactivity when you subscribe to a collection. Like this:
// enabled by default
Meteor.publish('top', function() {
return Top.find({},{reactive: false});
});
What is oplog?
Oplog is the MongoDB log. When you tell meteor to use oplog, reactivity performance is much better, unless you have a really high volumne of insert operations. In this cases may be wise to keep it disabled. Oplog can optimize your reactive DB calls by ~x5 ~x20.If you are going to use oplog you should optimize your db calls. You can read more about it here.
What methods exists to connect DBS to meteor?
Default connection:
Reactivity? yes. Oplog? yes. DB Limit? One. Description: Meteor creates a default MongoDB database when you run 'meteor'. You can set a different database using enviromental variables, or just MONGO_URL=mongodb://localhost:27017/db_name meteor.
DDP:
Reactivity? yes. Oplog? yes. DB Limit? no. Description: You need a meteor project for every DB. That's about 600MB in memory for every DB. You can read about it here and here.
MongoInternal (SOLUTION: Thanks to carlevans719):
Reactivity? yes. Oplog? yes. DB Limit? no. Description: You can specify a DB in your subscriptions file like:
ar database = new MongoInternals.RemoteCollectionDriver('mongodb://user:password#localhost:27017/meteor', {oplogUrl: "mongodb://localhost:27017/local"});
var numberOfDocs = database.open('boxes').find().count();
Last Words:
MongoInternal If you are not going to use the default db, you have to tell meteor to do not create it. To achieve this you must always run meteor as MONGO_URL=mongodb://localhost:27017 meteor
In Meteor, how do you Insert/Upsert to a Meteor Collection with Unacknowldeged Write Concern w=0?
Can the write concern be set during the insert/upsert, rather than as a environment variable?
Yes, you can pass writeConcern as of Mongo v2.6:
http://docs.mongodb.org/manual/reference/command/insert/#dbcmd.insert
No, you can't pass that option in Meteor. It's not documented here:
http://docs.meteor.com/#update
I did some digging to see what you'd have to do if you wanted to patch Meteor. Here is the link to their update/insert/upsert code:
https://github.com/meteor/meteor/blob/devel/packages/mongo/collection.js
It looks like it delegates to DDP which is their Distributed Data Persistence framework. Hope that helps.