Watchmaker
Watchmaker

Reputation: 5308

How would you test with Jasmine an Vanilla JS Ajax call that is done with a Promise?

I come from here: How to make an AJAX call without jQuery?

And it is difficult to mock the Promise, the AJAX call or both.

I have tried so far with jasmine-ajax but it seems to have a bug... and apparently "is only meant for browser environment".

I have also tried to mock the XMLHttpRequest object but without success.

So, I am not sure what my options are here:

function get(url) {
  return new Promise((resolve, reject) => {
    const req = new XMLHttpRequest();
    req.open('GET', url);
    req.onload = () => req.status === 200 ? resolve(req.response) : reject(Error(req.statusText));
    req.onerror = (e) => reject(Error(`Network Error: ${e}`));
    req.send();
  });
}

Upvotes: 1

Views: 582

Answers (1)

Krzysztof Safjanowski
Krzysztof Safjanowski

Reputation: 7438

Proof of concept how XMLHttpRequest can be mocked

function get(url) {
  return new Promise((resolve, reject) => {
    const req = new XMLHttpRequest();
    req.open('GET', url);
    req.onload = () => req.status === 200 ? resolve(req.response) : reject(Error(req.statusText));
    req.onerror = (e) => reject(Error(`Network Error: ${e}`));
    req.send();
  });
}

describe('XMLHttpRequest', function() {
  var xhr
  var urls

  beforeEach(() => {
    xhr = {
      open: (_type_, _url_) => {
        xhr.status = urls[_url_].status
        xhr.response = urls[_url_].response
        xhr.statusText = urls[_url_].statusText
      },
      send: () => {
        setTimeout(xhr.onload, 1)
      }
    }

    XMLHttpRequest = jasmine.createSpy(xhr).and.returnValue(xhr)
  })

  it('resolves query with `response`', function(done) {
    urls = {
      'http://foo/bar': {
        response: 'some other value',
        status: 200
      }
    };

    get('http://foo/bar')
    .then(r => expect(r).toBe('some other value'), e => expect(e).toBe(undefined))
      .then(done)
  })

  it('rejects query with `statusText`', function(done) {
    urls = {
      'http://baz/quux': {
        response: 'some other value',
        status: 500,
        statusText: 'some error'
      }
    };

    get('http://baz/quux')
    .then(r => expect(r).toBe(undefined), e => expect(e.message).toBe('some error'))
      .then(done)
  })
})
<script src="https://safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script>
<link href="https://safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" />

Upvotes: 1

Related Questions