moll / js-must

An assertion library for JavaScript and Node.js with a friendly BDD syntax (awesome.must.be.true()). It ships with many expressive matchers and is test runner and framework agnostic. Follows RFC 2119 with its use of MUST. Good stuff and well tested.
Other
336 stars 35 forks source link

Unexpected false-positive with promises #71

Closed MarcusNoble closed 6 years ago

MarcusNoble commented 6 years ago

I'm not sure if i've come across a bug or if my understanding of the API is incorrect but I am having trouble testing for a promise either resolving or rejecting.

I am testing similar to this:

const demand = require('must');

demand(testClass.shouldResolve()).to.resolve.to.equal(undefined);

When calling a function that returns a promise that resolves without a value. This passes as I'd expect it to.

The problem occurs when I switch out the function with one that rejects:

const demand = require('must');

demand(testClass.shouldReject()).to.resolve.to.equal(undefined);

This still passes, even though the promise rejected.


An example can be found here: https://glitch.com/edit/#!/icy-creator

The output of running these tests are:

$ npm test

> my-glitch-app@0.0.1 test /app
> mocha ./test.js

  example
    ✓ should resolve
    ✓ should reject
    ✓ should not resolve (this test should fail)
    ✓ should not reject (this test should fail)

  4 passing (11ms)

(node:20238) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): AssertionError: {"message":"Uh-oh!"} must equal "Uh-oh"
(node:20238) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:20238) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: Uh-oh!
(node:20238) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): AssertionError: Resolved
moll commented 6 years ago

Hey! Sorry you're having trouble.

It's true that it resolves to a promise that fails. What you need to do to have your test fail, too, is to pass that failing promise to Mocha for it to listen to it and not presume your test succeeded.

Doing something like the following should do it:

it("must pass", function() {
  return demand(Promise.resolve(false)).to.resolve.to.equal(true)
})

I myself usually find it easier to use CoMocha and use generators to not have to do so. Check out one of my open source websites for an full blown example: https://github.com/rahvaalgatus/rahvaalgatus. Particularly https://github.com/rahvaalgatus/rahvaalgatus/blob/master/test/mocha.opts and the controller tests at https://github.com/rahvaalgatus/rahvaalgatus/blob/master/test/controllers/home_controller_test.js.

MarcusNoble commented 6 years ago

Ah! Returning the assert works, as does awaiting that line.

Perhaps it's worth adding a little note to the readme?

moll commented 6 years ago

You're probably right wrt to README/docs. ;)