Giter Club home page Giter Club logo

Comments (1)

tomkis avatar tomkis commented on May 18, 2024

Well yeah, I didn't go into a depth because basically unit testing in redux-elm should follow the best practices of unit testing Sagas & Reducers.

Testing reducers is very easy:

it('should increment', () => {
   const initialState = reducer();

   expect(reducer(initialState, { type: 'Increment' })).toEqual(1);
});

So it's all about expecting output based on input.

Testing Sagas is theoretically easy, but it's not that easy in practice because you need to follow some good practices, like for example avoiding yield*:

function* apiSaga() {
   yield put({ type: 'SetLoadingSpinner' });
   try {
     yield call(api);
   } finally {
     yield put({ type: 'ResetLoadingSpinner' });
   }
}

// You better do this
function* rootSaga() {
    yield take('CallAPI');

    // You should realize that you can choose between call and fork
    // depending on use case
    yield call(apiSaga);
}

// Instead of this
function* rootSaga(){
    yield take('CallAPI');
    yield* apiSaga();
}

Because now you can write tests quite easily:

it('should call an API when CallAPI kicks in', function() {
   const it = rootSaga();

   // Saga should wait for CallAPI
   expect(it.next().value).toEqual(take('CallAPI'));

   // And then call the API
   // which is encapsulated in apiSaga, we don't need to test internals
   // because we just rely on the correctness proven by other unit test
   expect(it.next().value).toEqual(apiSaga);
});

it('should show spinner, call api and hide spinner', function() {
  const it = apiSaga();

  // Show the spinner
  expect(it.next().value).toEqual(put({ type: 'SetLoadingSpinner' }));

  // Call API
  expect(it.next().value).toEqual(call(api));

  // Hide the spinner
  expect(it.next().value).toEqual(put({ type: 'ResetLoadingSpinner' }));
});

it('should hide the spinner even when api fails', function() {
  const it = apiSaga();

  // Show the spinner
  expect(it.next().value).toEqual(put({ type: 'SetLoadingSpinner' }));

  // Call API
  expect(it.next().value).toEqual(call(api));

  // Even when API fails, just reset the spinner
  expect(it.throw(new Error('API error'))).toEqual(put({ type: 'ResetLoadingSpinner' }));
});

However, both of these examples should rather be part of redux and redux-saga.

from prism.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.