Force-failing a Jasmine test

JavascriptJasmine

Javascript Problem Overview


If I have code in a test that should never be reached (for example the fail clause of a promise sequence), how can I force-fail the test?

I use something like expect(true).toBe(false); but this is not pretty.

The alternative is waiting for the test to timeout, which I want to avoid (because it is slow).

Javascript Solutions


Solution 1 - Javascript

Jasmine provides a global method fail(), which can be used inside spec blocks it() and also allows to use custom error message:

it('should finish successfully', function (done) {
  MyService.getNumber()
  .success(function (number) {
    expect(number).toBe(2);
    done();
  })
  .fail(function (err) {
    fail('Unwanted code branch');
  });
});

This is built-in Jasmine functionality and it works fine everywhere in comparison with the 'error' method I've mentioned below.

Before update:

You can throw an error from that code branch, it will fail a spec immediately and you'll be able to provide custom error message:

it('should finish successfully', function (done) {
  MyService.getNumber()
  .success(function (number) {
    expect(number).toBe(2);
    done();
  })
  .fail(function (err) {
    throw new Error('Unwanted code branch');
  });
});

But you should be careful, if you want to throw an error from Promise success handler then(), because the error will be swallowed in there and will never come up. Also you should be aware of the possible error handlers in your app, which might catch this error inside your app, so as a result it won't be able to fail a test.

Solution 2 - Javascript

Thanks TrueWill for bringing my attention to this solution. If you are testing functions that return promises, then you should use the done in the it(). And instead of calling fail() you should call done.fail(). See Jasmine documentation.

Here is an example

describe('initialize', () => {

    // Initialize my component using a MOCK axios
    let axios = jasmine.createSpyObj<any>('axios', ['get', 'post', 'put', 'delete']);
    let mycomponent = new MyComponent(axios);

    it('should load the data', done => {
        axios.get.and.returnValues(Promise.resolve({ data: dummyList }));
        mycomponent.initialize().then(() => {
            expect(mycomponent.dataList.length).toEqual(4);
            done();
        }, done.fail);     // <=== NOTICE
    });
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBen AstonView Question on Stackoverflow
Solution 1 - JavascriptMichael RadionovView Answer on Stackoverflow
Solution 2 - JavascriptJohn HenckelView Answer on Stackoverflow