Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select * hangs forever if time is mocked with sinon #1267

Closed
ejlangev opened this issue Mar 11, 2016 · 5 comments
Closed

Select * hangs forever if time is mocked with sinon #1267

ejlangev opened this issue Mar 11, 2016 · 5 comments

Comments

@ejlangev
Copy link

Node version: 4.3.2
Knex version: 0.9.0
Pg version: 4.5.1
Sinon version: 1.17.3

Commenting out the sinon.useFakeTimers(Number(date)) causes this to run just fine. Otherwise it seems to hang forever.

var knex = require('knex');
var sinon = require('sinon');

var pg = knex({
    debug: true,
    client: 'pg',
    connection: {
        host: 'localhost',
        user: 'postgres',
        password: 'password',
        database: 'test_db'
    }
});

var date = new Date();
date.setDate(25);
date.setMonth(1);
clock = sinon.useFakeTimers(Number(date));

var table = pg('test_table');

table().select('*')
    .then(function(result) {
        console.log('NEVER REACHED');
    })
    .catch(function(err) {
        console.log('NEVER REACHED');
    })

Not sure if this is a problem with knex or with pg underneath though.

@ejlangev
Copy link
Author

Seems to be because pool2 relies on behavior of setTimeout. Using sinon.useFakeTimers(...) replaces several methods including setTimeout with synchronous versions which breaks it. Can fix by replacing with: clock = sinon.useFakeTimers(Number(date), 'Date');

@robwilkerson
Copy link

I see the same Knex/Sinon conflict using MySQL. I was re-deploying some old integration tests from less than a year ago with updated dependencies and was having a hell of a time figuring out why the code didn't work.

After lots of trial, even more error, restoring module state of the old app and working forward, it looks like something changed in v0.8.0 of Knex. If I roll Knex all the way back to 0.7.6, my existing code works fine. I can also verify that @ejlangev's workaround works. Here's my code with his changes:

beforeEach(function() {
    return fixtures.load(data)
        .then(function() {
            let date = new Date().getTime();
            clock = sinon.useFakeTimers(date, 'Date');
            return;
        });
});
afterEach(function() {
    return fixtures.clear(data)
        .then(function() {
            return clock.restore();
        });
});

Note that my fixtures methods return a Knex promise.

@w4-hojin
Copy link

API was updated

fakeClock = sinon.useFakeTimers({
        now: new Date().getTime(),
        toFake: ['Date'],
      });

@elhigu
Copy link
Member

elhigu commented Nov 14, 2017

I don't think this is knex's problem.

@elhigu elhigu closed this as completed Nov 14, 2017
@meelash
Copy link

meelash commented Oct 23, 2019

For posterity, you can use the shouldAdvanceTimers option on sinon.useFakeTimers or call clock.runAll to have this work correctly while stubbing setTimeout and other functions besides Date.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants