I am trying to write test script for some DB interaction. But the script always fails with "test exited without ending" error in promise. I have tried using async-await, promise-then and timeOut. But it always exits with "test exited without ending" error. Please help me with that.
Below is my code -
let test = require('tape');
let tapSpec = require('tap-spec');
let mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
import async from 'async';
import User from '../path-to-model';
test('Log In',(t)=>{
let username = "username";
let password = "password";
try{
let user = User.findOne({username: username}).select('password').exec();
setTimeout(function() {
if(user){
user.then((u)=>{
console.log('user',user);
t.pass('Got User');
//res(user);
t.end();
})
}
}, 5000);
} catch (e) {
//rej(e);
t.fail('Fail', e);
t.end();
}
})
Before you do anything async, you have to use t.plan - otherwise tape can't know that your test has assertions left to run.
@ljharb Thank you for replying. I had tried with t.plan. But the promise is not handled anyway. The async-await does not give any value. If I use then, code inside then block never executes, and test ends with error.
test('Log In', (t) =>{
t.plan(1); /// When trun on, gives plan != count error and test fails. When turned off gives 'test exited without ending' error
let username = "username";
let password = "password";
let user = User.findOne({username: username}).select('password').exec(); /// if i put async-await instead of then, i don't get any value form await.
user.then((u)=>{
//t.plan(2);
console.log('user', user);
t.equal(u.count, 1);
t.pass('Got User!');
});
//t.pass();
});
That's because an async function is sugar for "a function that returns a promise" - and tape doesn't look at the return value of your function.
In other words, if you use async/await, then you have to await every promise, and use try/catch, and t.fail() in the catch block.
@ljharb even if I do that, I never get the value for the handled promise by await and test always ends in error with 'test exited without ending'
@c-gargi can you show me your full async/await example?
@ljharb here is my code with async-await
test('Log In', async(t) =>{
let username = "username";
let password = "password";
try{
let user = await User.findOne({username: username}).select('password').exec();
t.equal(user.count, 1);
t.pass('Got User!');
} catch (e){
console.log('err', e)
t.fail('Fail');
}
});
Instead, use this:
test('Log In', async (t) =>{
t.plan(2); // without this, tape stops waiting for your test on the first `await`
const username = "username";
const password = "password";
try {
const user = await User.findOne({username: username}).select('password').exec();
t.equal(user.count, 1);
t.pass('Got User!');
} catch (e) {
console.log('err', e)
t.fail('Fail');
}
t.end();
});
This gives "plan != count" error and test fails @ljharb
1 instead of 2 then :-) the t.plan(x) is still necessary, you just have to get the count right.
Does not help @ljharb , control is not reaching any assert after the const user = await User.findOne ... line, hence assert count is always 0. The error shows
operator: fail
expected: 1
actual: 0
If I put t.equal(1, 1); above the await test passes without executing everything after await
test('Log In', async (t) =>{
t.plan(1); // without this, tape stops waiting for your test on the first `await`
const username = "username";
const password = "password";
try {
t.equal(1, 1);
const user = await User.findOne({username: username}).select('password').exec();
t.equal(user.count, 1);
t.pass('Got User!');
} catch (e) {
console.log('err', e)
t.fail('Fail');
}
t.end();
});
"operator: fail" means that it's hitting the catch.
t.plan(1) means that tape will mark the test as succeeded the instant it gets 1 passed assertion; it's got nothing to do with await.
Understood, but if the await is not working as expected, tape will never reach to the instant it gets 1 passed assertion.
It is working - it's generating an exception, and hitting your catch block.
I was just looking at whether tape is able to await async test functions (as an alternative to using plan()) and found this issue, but then also found https://github.com/parro-it/tape-async, which seems to resolve it. Just thought I'd leave it here in case anyone else was looking into it.
Most helpful comment
Instead, use this: