I've made a debounced saga to fetch data for a typeahead component. I'd like to write a unit test for it. What are to steps to assert that a Saga has been debounced? Are there any examples out there? I'm completely lost at how to write a unit test for this 馃槥 .
My debounced saga:
export function* getCompanies() {
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
yield call(delay, 250); // debounce getCompanies saga by 250 ms
const searchTerm = yield select(selectSearchTerm());
if (searchTerm === '') return; // cancel api fetch if term is empty
// fetch companies
const requestURL = `https://autocomplete-api.com/suggest?query=${searchTerm}`;
const companies = yield call(request, requestURL);
if (!companies.err) {
yield put(loadCompanies(companies.data)); // dispatch action: load companies
}
return;
}
export function* getCompaniesWatcher() {
while (yield take(FETCH_RESULTS)) {
yield call(getCompanies);
}
}
In fact there is a way I think, please take a look here - https://github.com/yelouafi/redux-saga/blob/master/test/sagaHelpers/takeLatest.js
It is a really similar example. If you really want to check this debouncing thing.
However you dont even need to check:
delay helper from redux-saga (import { delay } from 'redux-saga')yield call(delay, 250)call effect is created with correct arguments. Effects are description to saga what should be done by it. You actually do not need to check if it happened, just if saga was ordered to do somethingAlso in my opinion you do not need to use yield call(getCompanies). I guess you are exporting getCompanies, so it can be tested. For me its exporting just for testing purposes which is not ideal (in my opinion). You can yield* getCompanies() so in your test (after const it = getCompaniesWatcher()) calls to it.next will be delegated in to your underlaying iterator which is the one created by getCompanies, so it can stay hidden from the outside world and still works exactly the same. However that is my personal preference.
Most helpful comment
In fact there is a way I think, please take a look here - https://github.com/yelouafi/redux-saga/blob/master/test/sagaHelpers/takeLatest.js
It is a really similar example. If you really want to check this debouncing thing.
However you dont even need to check:
delayhelper fromredux-saga(import { delay } from 'redux-saga')yield call(delay, 250)calleffect is created with correct arguments. Effects are description to saga what should be done by it. You actually do not need to check if it happened, just if saga was ordered to do somethingAlso in my opinion you do not need to use
yield call(getCompanies). I guess you are exportinggetCompanies, so it can be tested. For me its exporting just for testing purposes which is not ideal (in my opinion). You canyield* getCompanies()so in your test (afterconst it = getCompaniesWatcher()) calls toit.nextwill be delegated in to your underlaying iterator which is the one created bygetCompanies, so it can stay hidden from the outside world and still works exactly the same. However that is my personal preference.