2016-11-30 7 views
1

Я довольно новичок в тестировании модулей, поэтому, пожалуйста, прошу прощения за любую ненужность.Модуль Тестирование редукционной асинхронной функции с Jest

У меня есть файл api.js, который имеет все функции вызова API для приложения. Каждая функция возвращает свое обещание. Вот как это выглядит:

api.js

const api = { 
    getData() { 
    return superagent 
     .get(apiUrl) 
     .query({ 
     page: 1, 
     }); 
    }, 
} 

Сейчас подходит к асинхронным действию Redux, что я пытаюсь проверить. Это выглядит примерно так:

getDataAction.js

export function getData(){ 
    return dispatch => { 
     api.getData() 
      .end((err, data) => { 
       if (err === null && data !== undefined) { 
       console.log(data); 
       } else if (typeof err.status !== 'undefined') { 
       throw new Error(`${err.status} Server response failed.`); 
       } 
      }); 
    } 
} 

Теперь в тестовом файле, я попытался это:

getDataAction.test.js

jest.mock('api.js'); 
describe('getData Action',() => { 
    it('gets the data',() => { 
    expect(store.dispatch(getData())).toEqual(expectedAction); 
    }); 
}); 

Это порождает ошибку:

TypeError: Cannot read property 'end' of undefined 

Что я делаю неправильно? Теперь я могу mock api.js с автозагрузчиком по умолчанию Jest, но как мне обрабатывать случай работы функции обратного вызова с end? Большое спасибо за любую помощь!

ответ

2

Ваш макет из api должен возвращать функцию, которая возвращает объект, который имеет end функцию:

import api from 'api' //to set the implantation of getData we need to import the api into the test 

// this will turn your api into an object with the getData function 
// initial this is just a dumb spy but you can overwrite its behaviour in the test later on 
jest.mock('api.js',()=> ({getData: jest.fn()})); 

describe('getData Action',() => { 
    it('gets the data',() => { 
    const result = {test: 1234} 
    // for the success case you mock getData so that it returns the end function that calls the callback without an error and some data 
    api.getData.mockImplementation(() => ({end: cb => cb(null, result)})) 
    expect(store.dispatch(getData())).toEqual(expectedAction); 
    }); 

it('it thows on error',() => { 

    // for the error case you mock getData so that it returns the end function that calls the callback with an error and no data 
    api.getData.mockImplementation(() => ({end: cb => cb({status: 'someError'}, null)})) 
    expect(store.dispatch(getData())).toThrow(); 
    }); 
});