Testing with Mocha and Chai consuming values from previous tests
Testing with Mocha and Chai consuming values from previous tests
I have some tests created with mocha
and chai
using TypeScript
, they actually work as expected. Each function returns a Promise
which runs a test
.
mocha
chai
TypeScript
Promise
test
My question is if is there anyway to consume on each test
the value returned by a previous test
without using the nesting you see below.
test
test
My concern is that if I have more test
the nesting code could be very annoying going to the right
test
import * as request from 'supertest';
import app from '../src/app';
import { Promise } from 'bluebird';
import * as dateformat from 'dateformat';
import Commons from '../../utils/commons';
import { expect } from 'chai';
...
// all the functions used below are defined over here
...
registerNonExistingUser(email, pass, role).then(
(jwtToken: string) => {
authenticateUserCorrectJwt(jwtToken).then(
(user) => {
authenticateUserWrongJwt().then(
() => {
loginUserWrongCredentials().then(
() => {
loginUserCorrectCredentials(email, pass).then(
(jwtToken: string) => {
getLocalUserInfoCorrectJwt(jwtToken, email).then(
(user) => {
createTodoAsEditor(jwtToken, todoTitle).then(
(todos) => {
checkTodoExistsWithCorrectTitle(jwtToken, todoTitle).then(
(todo: any) => {
deleteTodoWithCorrectIdAsEditor(jwtToken, todo._id).then(
(todo) => {
unregisterExistingUser({
'local.email': email,
}).then(
(user) => {
// console.log(Commons.stringify(user));
}
);
}
);
}
);
}
);
}
);
}
);
}
);
}
);
}
);
}
);
Any idea on how to beautify this?
[EDIT 1]
@bhoo-day suggestion did the trick:
registerNonExistingUser(email, pass, role)
.then((_jwtToken: string) => {
return authenticateUserCorrectJwt(_jwtToken);
})
.then((user) => {
return authenticateUserWrongJwt();
})
...
Now I'm wondering if I could transform the beginning of the chain, in order to be something like the following (which I tried but doesn't work). My goal is to put every function at the same level, including the very first function:
Promise.resolve()
.then(() => {
return registerNonExistingUser(email, pass, role);
})
.then((jwtToken: string) => {
return authenticateUserCorrectJwt(jwtToken);
})
.then((user) => {
return authenticateUserWrongJwt();
})
...
[EDIT 2]
I tried the following and it works. Do you have any idea on how to simplify it?, maybe using: Promise.resolve()...
?
Promise.resolve()...
new Promise((resolve) => {
it('dummy', (done) => { resolve(); return done(); });
})
.then(() => {
return registerNonExistingUser(email, pass, role);
})
.then((_jwtToken: string) => {
return authenticateUserCorrectJwt(_jwtToken);
})
Thanks!
1 Answer
1
If you use promise, you could avoid this callback hell because that is the main purpose of promise.
Some ideas to solve the issue.
// temp variable to store jwt token
let token;
registerNonExistingUser(email, pass, role)
.then((jwtToken: string) => {
token = jwtToken; // assign it so other functions can use it
return authenticateUserCorrectJwt(jwtToken)
})
.then((user) => authenticateUserWrongJwt())
.then(() => loginUserWrongCredentials())
.then(() => loginUserCorrectCredentials(email, pass))
.then((jwtToken: string) => getLocalUserInfoCorrectJwt(jwtToken, email))
.then((user) => createTodoAsEditor(token, todoTitle))
.then((todos) => checkTodoExistsWithCorrectTitle(token, todoTitle))
.then((todo: any) => deleteTodoWithCorrectIdAsEditor(token, todo._id))
.then((todo) => unregisterExistingUser({ 'local.email': email }))
.then((user) => {
// console.log(Commons.stringify(user));
});
or if you use node 7.6.0 or higher, you can use async/await. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
async function printUser() {
try {
let jwtToken = await registerNonExistingUser(email, pass, role);
const user = await authenticateUserCorrectJwt(jwtToken);
await loginUserWrongCredentials();
jwtToken = await loginUserCorrectCredentials(email, pass);
const user = await getLocalUserInfoCorrectJwt(jwtToken, email);
const todos = await createTodoAsEditor(token, todoTitle);
const todo = await checkTodoExistsWithCorrectTitle(token, todoTitle)
const todo = await deleteTodoWithCorrectIdAsEditor(token, todo._id);
const user = await unregisterExistingUser({ 'local.email': email });
console.log(Commons.stringify(user));
} catch (error) {
// catch error here
}
}
@davidesp that is supposed to work with your
Promise.resolve().then
solution. Can you do breakpoint using debugger or add console.log
there?– bhoo-day
Jul 2 at 5:34
Promise.resolve().then
console.log
when using:
Promise.resolve()
I added a breakpoint on the first return
and the debugger stops there, but at the same time the testing finalizes right away. Then when I continue the debugging, it doesn't stop on the second return
(I think the execution finalized or jumps to the end). In the other, if I use your version, when it stops on the first return
the testing doesn't finalize yet, the I can continue pressing F5
to jump from return
to return
as expected.– davidesp
Jul 2 at 5:53
Promise.resolve()
return
return
return
F5
return
return
Perhaps we can try with
return Promise.resolve().then
or use done()
at the last function from mocha mochajs.org/#asynchronous-code– bhoo-day
Jul 2 at 6:04
return Promise.resolve().then
done()
I just added [EDIT 2] with one working example. Do you think we could simplify it?, please, check above. Thanks!
– davidesp
Jul 2 at 9:10
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
thanks @bhoo-day, your suggestion did the trick. Do you have maybe one suggestion for the question I just added on my edition above?
– davidesp
Jul 2 at 5:19