30

I have a mocha test using chai's expect:

it("should parse sails out of cache file", async () => {
    const sailExtractor = new Extractor();
    const result = await sailExtractor.extract("test.xml");

    try {
        expect(result.length).to.be.greaterThan(0);
        const withMandatoryFlight = result.filter((cruises) => {
            return cruises.hasMandatoryFlight === true;
        });
        expect(withMandatoryFlight.length).to.be.greaterThan(0);
        const cruiseOnly = result.filter((cruises) => {
            return cruises.hasMandatoryFlight === false;
        });

        expect(cruiseOnly.length).to.be.greaterThan(0);

        return Promise.resolve();
    } catch (e) {
        return Promise.reject(e);
    }
}

Now if one to.be.greaterThan(0) expectation fails, the error output on mocha is not dev-friendly:

 AssertionError: expected 0 to be above 0
      at Assertion.assertAbove (node_modules/chai/lib/chai/core/assertions.js:571:12)
      at Assertion.ctx.(anonymous function) [as greaterThan] (node_modules/chai/lib/chai/utils/addMethod.js:41:25)
      at _callee2$ (tests/unit/operator/croisiEurope/CroisXmlExtractorTest.js:409:61)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:65:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:303:22)
      at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:117:21)
      at fulfilled (node_modules/tslib/tslib.js:93:62)
      at <anonymous>
      at process._tickDomainCallback (internal/process/next_tick.js:228:7)

I would like to replace it with something more human-friendly. Is there a way to tell chai to use a customize error message?

I want to be able to use it like this pseudo-code:

 expect(result.length)
      .to.be.greaterThan(0)
      .withErrorMessage("It should parse at least one sail out of the flatfile, but result is empty");

And then the failing mocha error should print:

 AssertionError: It should parse at least one sail out of the flatfile, but result is empty
k0pernikus
  • 60,309
  • 67
  • 216
  • 347

2 Answers2

45

Every expect method accepts an optional parameter message:

expect(1).to.be.above(2, 'nooo why fail??');
expect(1, 'nooo why fail??').to.be.above(2);

So, in your case it should be:

expect(result.length)
  .to.be.greaterThan(0, "It should parse at least one sail out of the flatfile, but result is empty");
alexmac
  • 19,087
  • 7
  • 58
  • 69
  • OP is using `chai`, but it looks like your answer applies to that library as well. Alternativelty, you can use `expect(result.length, 'It should parse...').to.be.greaterThan(0)` – robertklep Aug 14 '17 at 16:36
  • 1
    Sidenote: Since I'm using typescript, I could have found that one out myself by jumping into the `greaterThan` method, as its typing is declared as [`NumberComparer` interface](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/9030f8f40fb13aef2242c2d011d98a7a03044083/types/chai/index.d.ts#L157), and there the optional message parameter is shown. – k0pernikus Aug 14 '17 at 17:20
1

If you use should for your assertions you can pass a string to the test function which will be written out if the condition fails. For example:

result.length.should.be.above(0, "It should parse at least one sail out of the flatfile, but result is empty");

I'm not sure if this is possible with expect. The API doesn't seem to mention it.

robjwilkins
  • 5,462
  • 5
  • 43
  • 59
  • this is not working for me, but the chai expect custom message is. – liminal18 May 22 '19 at 14:04
  • 1
    I realise this is old now, but just to confirm that this *does* work for me with syntax `myCollection.should.have.length(1, "oopsy");`. Odd how it did not for @liminal18. Thanks for the answer! – Adam Cameron Jan 22 '21 at 18:00