Async Mocha done() isn't called in my function - javascript

I call this function, console log is called but done() is not called:
import {Database} from "../../code/server/Database";
import 'mocha'
const expect = require('chai').expect
describe('Database save', function() {
it('should save without error', function(done) {
Database.saveSessionData(1, 2, 3, function(err, docs) {
expect(err).to.equal(null)
expect(docs.sessionOpenTime).to.equal(1)
expect(docs.sessionCloseTime).to.equal(2)
expect(docs.sessionLength).to.equal(3)
console.log(2222)
done()
})
})
})
Here is the result, 'Running tests' continues spinning on forever:
But if I change the 'Database' code into this, it works as expected:
setTimeout(function () {
console.log('lol')
done()
}, 1000)
What am I missing here?

Mocha test hangs since you have an opened database connection.
There are two options to solve this problem:
If you do not need a real database connection in your tests:
you can use sinon.stub() (https://www.npmjs.com/package/sinon) to return a predetermined response for async methods you use in your tests or sinon.spy() to make sure a stubbed method called exact number of times.
Here's a good article I just found to illustrate how to use sinon.js: https://semaphoreci.com/community/tutorials/best-practices-for-spies-stubs-and-mocks-in-sinon-js.
you can implement a dependency injection container to be able to replace your implementation of Database class to a Database class that does not perform I/O operations.
Although dependency injection implementations may vary depending on requirements some simple implementations are also available:
https://blog.risingstack.com/dependency-injection-in-node-js/
If you need to perform a real connection in your tests:
Consider adding an after hook to your mocha tests:
let's say mongodb is used as a database (it does not matter, but it would
be an actual working example)
const mongoose = require('mongoose');
const expect = require('chai').expect;
mongoose.connect('mongodb://localhost/test');
after(() => {
mongoose.connection.close();
});
describe('db connection', () => {
it('should make a test', () => {
expect(1).to.equal(1);
});
});

Related

Jest mock different return values for a function in each test

I want to have different values returned for the same mock in each Test.
I am using mockReturnValueOnce for returning different values in each call of a test.
But for further test when I use mockImplementationOnce it still returns mockReturnValue.
const mock = require('module-to-mock');
jest.mock('module-to-mock');
describe('tests', () => {
it('test #1', async () => {
mock.foo = jest
.fn()
.mockReturnValueOnce(1) // First call
.mockReturnValueOnce(2) // Seconds call
.mockReturnValue("default"); // Rest of the calls
// execute test
});
it('test #2', async () => {
mock.foo.mockImplementationOnce(() => 3);
// It is not working I am getting "default"
// execute test
});
});
I did try resetting the mock using mock.foo.mockReset(), but it did not help. I did add it at the end of each test, once the test is executed. I also try by adding at the beginning of each test.
I have common mock implementation for all the functions in module-to-mock in a separate file.
I just want to remove/reset the mock done in the test #1 and move to the original mock done in a separate file.

Creating single knex connection pool for all tests in jest

I use knex in my project and I try to write tests with it (with jest). I want to execute some scripts before each test and after each test, so each test will run on the same data in db.
I tried to create a global connection pool with knex, and execute the scripts in the tests setup. The problem is when I have tests in different describe scope.
For example, lets say I have 2 tests, each test is in different describe scope
import { connection } from './global-setup.ts'
describe('first', () => {
beforeEach( async () => {
await connection.raw(...)
}
afterEach( async () => {
await connection.raw(...)
}
it('test1', () => {...})
}
and same for the second test. The result is that the scripts in beforeEach is not always run, And as a result the second tests sometimes pass, and sometimes fail.
I did noticed that the connection pool is initalized every time for different describe scope, which I think is the cause of the problem. (and if I put the first and the second test in the same describe scope they always pass)
How can I fix this? or how can I make one connection pool for all the describe tests?

Error: Timeout of 30000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves

I am trying to write tests for electron using spectron.
This is my code.
describe ('Application launch', function(done) {
this.timeout(30000);
const app = new Application({
path: electronBinary,
args: [baseDir],
});
before(() => app.start());
after(() => app.stop());
it('shows an initial window', async () => {
await app.client.waitUntilWindowLoaded();
const count = await app.client.getwindowcount();
assert.equal(count,1);
});
});
However, When I run npm test The error I get is
1) Application launch "before all" hook:
Error: Timeout of 30000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.
2) Application launch "after all" hook:
Error: Application not running
at Application.stop (node_modules\spectron\lib\application.js:58:48)
at Context.after (test\spec.js:19:19)
Do I need to add any functions to the existing hooks?
It appears to be happening in your before all method. Notice that your error says 1) Application launch "before all" hook:.
So your actual test function looks fine to me. And I don't see a beforeAll anywhere in this example code so I would say there is one of two possible problems.
There is a beforeAll method with an issue somewhere not in this code sample.
The before hook shown here is returning a non-promise object.
In your code you are using a lambda function to do the work of before but if app.start() is returning an object which is not a promise then that would be your issue. Try refactoring it more like this:
before(() => {
app.start()
})
If your app.start() function is asynchronous you may need to pass the done handler into it:
before((done) => {
app.start(done)
})
Or possibly convert your app.start() function to return a promise which should resolve it. You may need to add async () => await app.start() but I don't think that would be necessary for a single expression like this.
You didn't use "done" as a callback in your it-function. You also don't have to use done in the describe callback. Also, since done() already makes your code asynchronous, you don't have to use the async keyword.
My solution:
describe ('Application launch', function() {
this.timeout(30000);
const app = new Application({
path: electronBinary,
args: [baseDir],
});
before(() => app.start());
after(() => app.stop());
it('shows an initial window', (done) => {
await app.client.waitUntilWindowLoaded();
const count = app.client.getwindowcount();
assert.equal(count,1);
done();
});
});
Hope it helps!

Unit testing http methods (get, post) in react / javascript using intern

This is my first time writing unit tests - please be nice.
I am trying to write unit tests for two functions. one function is to GET a number from the api, and the other is to POST data.
I am not sure how to do this. I know, I want to use the intern "expect" call and fetch-mock but the rest I want to do in react / javascript. I made a mock response with some data.
My questions are:
How can I use fetch-mock to compare my expected output with what my function is outputting
How does my mock response data relate to fetch-mock?
Again, I have not done this before and i am having a hard time understanding the resources available online (have been researching this for 8+ hours) so i am looking for another opinion
I haven't used fetch-mock before, and there are many ways to go about something like this, but the general process for mocking is to setup the mock, do what you need to do, and tear it down in an after or afterEach. How you actually go about checking whether your GET request worked depends on how you go about making the request in the first place.
A test for a mock request might look something like this. The assumption here is that you have a request method that makes a request and returns a Promise (what you'd get if you did return fetch('some_url')).
import * as fetchMock from 'fetch-mock';
const { describe, it, afterEach } = intern.getPlugin('interface.bdd');
const { expect } = intern.getPlugin('chai');
describe('my suite', () => {
afterEach(() => {
fetchMock.restore();
});
it('should do something', () => {
fetchMock.get('*', { hello: 'world' });
return thingThatDoesAGetRequest.then(response => {
expect(response).to.equal({ hello: 'world' });
});
})
});
Another option would be to wait for the mock request to complete rather than looking at a function return value:
it('should do something', test => {
// Create a promise that will resolve when a request is made
const promise = new Promise(resolve => {
fetchMock.get('*', () => {
resolve();
return { hello: 'world' }
});
});
// Do whatever should be making a call
thingThatDoesAGetRequest();
// Wait for the request promise to resolve, then see if whatever
// you expect to happen has happened
return promise.then(() => {
expect(something).to.equal({ hello: 'world' });
});
})

Mocha change timeout for afterEach

I am writing a node application with mocha and chai. Some of the tests call an external API for integration tests, which might take up to 90sec to perform the action.
In order to cleanup properly, I defined an afterEach()-block, which will delete any generated remote resources, in case an expect fails and some resources weren't deleted.
The tests themselves have an increased timeout, while the rest of the tests should retain their default and small timeout:
it('should create remote resource', () => {...}).timeout(120000)
However, I can't do the same with afterEach().timeout(120000), because the function does not exist - nor can I use the function ()-notation due to the unknown resource names:
describe('Resources', function () {
beforeEach(() => {
this._resources = null
})
it('should create resources', async () => {
this._resources = await createResources()
expect(false).to.equal(true) // fail test, so...
await deleteResources() // will never be called
})
afterEach(async() => {
this._resources.map(entry => {
await // ... delete any created resources ...
})
}).timeout(120000)
})
Any hints? Mocha is version 4.0.1, chai is 4.1.2
The rules are same for all Mocha blocks.
timeout can be set for arrow functions in Mocha 1.x with:
afterEach((done) => {
// ...
done();
}).timeout(120000);
And for 2.x and higher it, beforeEach, etc. blocks are expected to be regular functions in order to reach spec context. If suite context (describe this) should be reached, it can be assigned to another variable:
describe('...', function () {
const suite = this;
before(function () {
// common suite timeout that doesn't really need to be placed inside before block
suite.timeout(60000);
});
...
afterEach(function (done) {
this.timeout(120000);
// ...
done();
});
});
Mocha contexts are expected to be used like that, since spec context is useful, and there are virtually no good reasons to access suite context inside specs.
And done parameter or promise return are necessary for asynchronous blocks.
If you need to use dynamic context you have to use normal function.
describe('Resources', function () {
// ...
afterEach(function (){
this.timeout(120000) // this should work
// ... delete any created resources ...
})
})

Categories

Resources