Lukas
Lukas

Reputation: 10360

Jest does not recognize calls on spies in promise

I want to test a method that calls a function in a promise.

article-api.js (simplified)

articleMiddleware(next) {
    return fetch(articleApiListUrl, { headers, method, body })
        .then(() => next({ some: 'data'}));

}

This is a simplified version of article-api.js, full code can be seen here: https://gist.github.com/LukasBombach/7bd9cce28d3a3b905fb8a408b37de3a9

I want to see if next has been called with { some: 'data'}. I use fetch-mock to mock my fetch request

article-api.spec.js (simplified)

describe('article api middleware', () => {

    it('creates ARTICLE_SUCCESS when fetching an article has been done', () => {
        fetchMock.post('*', { some: 'data' });
        return articleMiddleware(next)
            .then(expect(next).toBeCalledWith({ some: 'data' }))
            .then(() => fetchMock.restore());

    });

});

This is a simplified version of article-api.spec.js, full code can be seen here: https://gist.github.com/LukasBombach/178f591f516fe13c24fb0a4f02c4676c

What I get though is

Expected mock function to have been last called with: [{ some: 'data' }] But it was not called.

If you view the full code in the two gists you'll find my code is a little bit different, the error messag there is

expect(received).toBe(expected)

Expected value to be (using ===):
  2
Received:
  1

This is because of next(action) in line 17 in the first gist calls next (syncroneously) but the next inside the promise never gets called.

Upvotes: 3

Views: 409

Answers (1)

Lin Du
Lin Du

Reputation: 102287

Here is the solution only using "jest": "^24.8.0", no need to use fetch-mock, you can mock it manually by yourself.

article-api.js:

const fetch = require('node-fetch');

function articleMiddleware(next) {
  const articleApiListUrl = 'https://github.com/mrdulin';
  const headers = {};
  const method = 'get';
  const body = {};

  return fetch(articleApiListUrl, { headers, method, body }).then(() => next({ some: 'data' }));
}

exports.articleMiddleware = articleMiddleware;

article-api.spec.js:

jest.mock('node-fetch');

const fetch = require('node-fetch');
const { articleMiddleware } = require('./article-api');

describe('articleMiddleware', () => {
  it('t1', async () => {
    fetch.mockResolvedValueOnce({});
    const next = jest.fn();
    await articleMiddleware(next);
    expect(fetch).toBeCalledWith('https://github.com/mrdulin', { headers: {}, method: 'get', body: {} });
    expect(next).toBeCalledWith({ some: 'data' });
  });
});

Unit test result with 100% coverage:

 PASS  src/stackoverflow/42676657/article-api.spec.js
  articleMiddleware
    ✓ t1 (9ms)

----------------|----------|----------|----------|----------|-------------------|
File            |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------------|----------|----------|----------|----------|-------------------|
All files       |      100 |      100 |      100 |      100 |                   |
 article-api.js |      100 |      100 |      100 |      100 |                   |
----------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.131s

Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/42676657

Upvotes: 1

Related Questions