Redux - Testing Slices & Thunks
Unit-test Redux logic without external tools by calling reducers and thunks directly and asserting results.
Try it: Test a slice reducer
View source
const { createSlice } = RTK;
function assert(name, cond){ const el=document.getElementById('test-out'); const li=document.createElement('li'); li.textContent=`${cond?'PASS':'FAIL'} - ${name}`; li.style.color=cond?'limegreen':'salmon'; el.appendChild(li); }
const slice = createSlice({ name:'counter', initialState:{value:0}, reducers:{ inc(s){s.value++}, addBy(s,a){s.value+=a.payload} } });
const r = slice.reducer;
let s = { value:0 };
s = r(s, slice.actions.inc());
assert('inc increments', s.value===1);
s = r(s, slice.actions.addBy(4));
assert('addBy adds payload', s.value===5);
Try it: Test an async thunk
View source
const { createSlice, configureStore, createAsyncThunk } = RTK;
const fetchData = createAsyncThunk('d/fetch', async ()=>{ await new Promise(r=>setTimeout(r,50)); return 42; });
const slice2 = createSlice({ name:'d', initialState:{status:'idle', value:null}, reducers:{}, extraReducers:b=>{
b.addCase(fetchData.pending,(s)=>{s.status='loading'})
.addCase(fetchData.fulfilled,(s,a)=>{s.status='succeeded'; s.value=a.payload})
.addCase(fetchData.rejected,(s)=>{s.status='failed'})
}});
const store = configureStore({ reducer:{ d:slice2.reducer } });
(async function(){
function assert(name, cond){ const el=document.getElementById('test-out2'); const li=document.createElement('li'); li.textContent=`${cond?'PASS':'FAIL'} - ${name}`; li.style.color=cond?'limegreen':'salmon'; el.appendChild(li); }
let s = store.getState();
assert('initial idle', s.d.status==='idle');
const p = store.dispatch(fetchData());
s = store.getState();
assert('pending', s.d.status==='loading');
await p; s = store.getState();
assert('fulfilled', s.d.status==='succeeded' && s.d.value===42);
})();