Unit testing mongoose method - javascript

I'm new to unit testing, can't wrap my head what I should unit test given this function ? Note that I don't want to hit database, so I need to mock/stub mongoose built in function "findById" maybe ? Can't figure it out big picture here :).
Not asking for complete solution, just an idea or some pointer to go from there.
LyricSchema.statics.like = function(id) {
const Lyric = mongoose.model('lyric');
return Lyric.findById(id)
.then(lyric => {
++lyric.likes;
return lyric.save();
})
}
Thank you !

Mockgoose
https://github.com/mockgoose/mockgoose
But this creates a in memory Database. And the database will serve the actual calls.

This is simple tdd test. I'm use Mocha + chai:
const chai = require('chai');
const expect = chai.expect;
const mongoose = require('mongoose');
const Lyric= mongoose.models.Lyric;
describe("Lyric test", () => {
let lyricId;
//create lyric document
beforeEach(done => {
Lyric.create({...})
.then(result=>{
lyricId = result._id;
done();
})
});
//remove lyric document after test
afterEach(done=>{
Lyric.remove({_id: lyricId})
.then(()=>{
done();
})
});
//test like function
it('like test', done=>{
Lyric.like(lyricId)
.then(result=>{
expect(result.likes).equal(1);
done();
})
.catch(err=>{throw err;})
});
})

Related

kubernetes-client javascript - create job from cronjob

What will be the equivalent for creating a job:
kubectl -n my-ns create job --from=cronjob/my-cron-job my-job
using javascript kubernetes-client ?
Found the solution to my question, with the help of this comment
This is how it looks like with javascript kubernetes-client, used in a pod inside the cluster (rbac permission might be needed, im running on k8s docker-desktop so didnt need):
const createJobFromCronJob = async (
cronJobNamespace: string,
cronJobName: string,
jobNamespace: string,
jobName: string) => {
// next 4 lines can be initialized somewhere else
const kubeConfig = new k8s.KubeConfig();
kubeConfig.loadFromCluster();
const batchV1Api = kubeConfig.makeApiClient(k8s.BatchV1Api);
const batchV1beta1Api = kubeConfig.makeApiClient(k8s.BatchV1beta1Api);
try {
const cronJob = await batchV1beta1Api.readNamespacedCronJob(cronJobName, cronJobNamespace);
const cronJobSpec = cronJob.body.spec.jobTemplate.spec;
const job = new k8s.V1Job();
const metadata = new k8s.V1ObjectMeta();
job.apiVersion = 'batch/v1';
job.kind = 'Job';
job.spec = cronJobSpec;
metadata.name = jobName;
metadata.annotations = {
'cronjob.kubernetes.io/instantiate': 'manual',
};
job.metadata = metadata;
const result = await batchV1Api.createNamespacedJob(jobNamespace, job);
console.log('job created');
} catch (err) {
console.error(`failed to create job: ${err.message}`);
throw err;
}
}
No, unfortunately you can't.
Please check my old answer in Create job from cronjob in kubernetes .yaml file question.
In short: you are able to do that (create job from cronjob) only using kubectl cli
Way to create regular job, without --from=cronjob:
const k8s = require('#kubernetes/client-node');
const kc = new k8s.KubeConfig();
kc.loadFromCluster();
const k8sBatchV1Api = kc.makeApiClient(k8s.BatchV1Api);
//creation of the job
k8sBatchV1Api.createNamespacedJob('dev', {
apiVersion: 'batch/v1',
kind: 'Job',
metadata: {
...
}
},
spec: {
...
}
}
}}).catch(e => console.log(e))
Example was taken from #Popopame answer in How to create a Job and a secret from Kubernetes Javascript Client

Setting up database for e2e testing fails: E11000 duplicate key error collection

I am having some troubles trying to set up a database for testing purposes. The data stored in the database should be removed an re-populated for each test. I am currently doing the following:
db.js
const mongoose = require('mongoose');
// a Mongoose model describing an entity
const Entity = require('entity-model');
// entities.mock is an array containing entity objects.
const mockedEntities= require('./entities.mock');
function setUp() {
Entities.collection.insertMany(mockedEntities);
}
function breakDown() {
mongoose.connection.on('connected', () => {
mongoose.connection.db.dropDatabase();
});
}
module.exports = { setUp, breakDown };
Then in my test.js:
const db = require('./db');
describe('e2e tests to make sure all endpoints return the correct data from the database', () => {
beforeEach(async () => {
await db.breakDown();
db.setUp();
});
it('should check store-test-result (UR-101)', (done) => ...perform test);
it('should check store-nirs-device (UR-102)', (done) => ...perform test);
});
It seems like I am not emptying out the database before re-populating it correctly. Any advise as to what could be the cause?
I ended up doing:
beforeEach(async () => {
await MyEntity.collection.drop();
await MyEntity.collection.insertMany(mockedMyEntity);
});
This solved my issue.
In case this result in an Mongo Error ns not found you need to explicitly create the collection in the database before dropping it. This happens if the collection does not exist. You can do this by adding a before:
before(async () => {
await MyEntity.createCollection();
});
Do not set option: autoCreate to true in you model as this should not be set to false in production according to https://mongoosejs.com/docs/guide.html#autoCreate.

TypeError: stub expected to yield, but no callback was passed returned from unit test

I am trying to write a unit test that should perform an integration test between a REST endpoint and the controller belonging to it. The test should mock the call to the database so no database connection is established during testing.
I am using chai-http to make the HTTP call to the endpoint and sinon with sinon-mongoose to mock the Mongoose models calls.
const set = [{ _id: 1 }, { _id: 2 }, { _id: 3 }];
//Require the dev-dependencies
const sinon = require('sinon');
const { describe, it } = require('mocha');
require('sinon-mongoose');
const chai = require('chai');
const chaiHttp = require('chai-http');
const server = require('../src/server');
const should = chai.should();
// set up mocks
const MyModel = require('../src/models/myModel');
const MyModelMock = sinon.mock(MyModel);
MyModelMock.expects('find').yields(set);
chai.use(chaiHttp);
describe('My endpoints', () => {
describe('/GET to my endpoint', () => {
it('it should GET all the info I want', (done) => {
chai.request(server)
.get('/api/myEndpoint')
.end((err, res) => {
res.should.have.status(200);
done();
});
});
});
});
Googling this error did not yield any results that I am able to work with. What am I doing wrong here?
In case someone ever runs into this (most likely future me).
I managed to solve my issue. I was using promises in my code and should have set up my mock accordingly (also chaining correctly).
MyModelMock.expects('find').chain('where').chain('in').chain('exec').resolves(set);

I am not able to connect to mongoose through my server

I am trying to connect to mongoose through my server but failing to do so.
I have already tried to put it into a try catch block but it says db.close or client.close is not a function. when I try to connect, I am getting an error "Unhandled promise rejection warning".
I would be glad if anyone could help me with this
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
const client = mongoose.connect('mongodb://localhost:27017/customercli', {
useNewUrlParser: true });
// import the model
const Customer = require('./models/customer');
// Add customer
const addCustomer = (customer) => {
Customer.create(customer).then(customer => {
console.info("New Customer Added");
client.close();
});
}
// Find customer
const findCustomer = (name) => {
//Make this case insensitive
const search = new RegExp(name, 'i') // here lowercase i made it
insensitive
Customer.find({$or: [{firstname: search}, {lastname: search}]})
.then(customer => {
console.log(customer);
console.log(`${customer.length} matches`);
client.close();
});
}
//Export all methods
module.exports = {
addCustomer,
findCustomer
}
I found the way to do this by myself. The connection to mongoose through my server was not getting closed. so i replaced db.close() with mongoose.connection.close() and it worked just fine.

spying on a dependency in a nodejs unit test

I'm using mocha and sinon for nodejs unit tests. I have the following
users.js
const Database = require('./lib/Database');
exports.setupNewUser = (name) => {
var user = {
name: name
};
try {
Database.save(user);
}
catch(err) {
console.error('something failed');
}
}
Database.js
exports.save = (user) => {
console.log(`saving: ${user}`);
};
userTest.js
const sinon = require('sinon');
require('chai').should();
const users = require('../src/users');
describe('users', () => {
it('should log an error when the Database save fails', () => {
var databaseSpy = sinon.spy(Database, 'save').throws(); // this is supposed to work??
users.setupNewUser('Charles');
databaseSpy.should.be.called;
});
});
According to the sinon tutorials I've read, I should be able to create that databaseSpy but I keep getting this error: ReferenceError: Database is not defined
What am I missing?
This seems like it might be a pathing issue. Your require might not be getting the correct path.
users.js
const Database = require('./lib/Database');
Where is /lib/Database in relation with the users.js file? I think that might be a good place to start looking.

Categories