Blog>
Snippets

Isolating Selector Logic for Testing

Create a small suite of selectors that are easy to test in isolation, demonstrating how to structure selectors to hide the state shape and facilitate testing.
// Selector to get all todos
const selectTodos = state => state.todos;

// Selector to get completed todos
const selectCompletedTodos = createSelector(
  [selectTodos],
  todos => todos.filter(todo => todo.completed)
);

// Selector to get the number of completed todos
const selectNumCompletedTodos = createSelector(
  [selectCompletedTodos],
  completedTodos => completedTodos.length
);
Defines basic selectors for a todo application. `selectTodos` is a basic selector to get all todos. `selectCompletedTodos` uses `selectTodos` to filter and get only completed todos. `selectNumCompletedTodos` uses `selectCompletedTodos` to count how many todos are completed.
// Selector to get todos with a specific tag
const selectTodosByTag = (state, tag) => state.todos.filter(todo => todo.tags.includes(tag));
Defines a selector `selectTodosByTag` that filters todos by a specific tag. It's not memoized as it receives a dynamic parameter `tag`.
// Testing selectors
// Mock state for testing
const mockState = {
  todos: [
    { id: 1, text: 'Learn Redux', completed: false, tags: ['coding', 'study'] },
    { id: 2, text: 'Read 1984', completed: true, tags: ['reading'] },
    { id: 3, text: 'Buy groceries', completed: true, tags: [] }
  ]
};

// Test selectCompletedTodos
console.assert(JSON.stringify(selectCompletedTodos(mockState)) === '[{"id":2,"text":"Read 1984","completed":true,"tags":["reading"]},{"id":3,"text":"Buy groceries","completed":true,"tags":[]}]', 'selectCompletedTodos test failed');

// Test selectNumCompletedTodos
console.assert(selectNumCompletedTodos(mockState) === 2, 'selectNumCompletedTodos test failed');
Provides an example of how to test the selectors using a mock state. The `selectCompletedTodos` and `selectNumCompletedTodos` selectors are tested against expected results.