Force-failing a Jasmine test

2020-06-30 04:35发布

问题:

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).

回答1:

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.



回答2:

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
    });
});