# Redux framework Grafana uses [Redux Toolkit](https://redux-toolkit.js.org/) to handle Redux boilerplate code. > **Note:** Some of our reducers are used by Angular; therefore, consider state to be mutable for those reducers. ## Test functionality Here's how to test the functioning of your Redux reducers. ### reducerTester Use the Fluent API framework to simplify the testing of reducers. #### Usage Example of `reducerTester` in use: ```typescript reducerTester() .givenReducer(someReducer, initialState) .whenActionIsDispatched(someAction('reducer tests')) .thenStateShouldEqual({ ...initialState, data: 'reducer tests' }); ``` #### Complex usage Sometimes you encounter a _resulting state_ that contains properties that are hard to compare, such as `Dates`, but you still want to evaluate whether other props in state are correct. In these cases, you can evaluate individual properties by using `thenStatePredicateShouldEqual` function on `reducerTester` that will return the resulting state. For example: ```typescript reducerTester() .givenReducer(someReducer, initialState) .whenActionIsDispatched(someAction('reducer tests')) .thenStatePredicateShouldEqual((resultingState) => { expect(resultingState.data).toEqual('reducer tests'); return true; }); ``` ### thunkTester Here's a Fluent API function that simplifies the testing of thunks. #### Usage Example of `thunkTester` in use: ```typescript const dispatchedActions = await thunkTester(initialState).givenThunk(someThunk).whenThunkIsDispatched(arg1, arg2, arg3); expect(dispatchedActions).toEqual([someAction('reducer tests')]); ``` ## Typing of connected props It is possible to infer connected props automatically from `mapStateToProps` and `mapDispatchToProps` using a helper type `ConnectedProps` from Redux. For this to work properly, split the `connect` call into two parts like so: ```typescript import { connect, ConnectedProps } from 'react-redux'; const mapStateToProps = (state: StoreState) => { return { location: state.location, initDone: state.panelEditor.initDone, uiState: state.panelEditor.ui, }; }; const mapDispatchToProps = { updateLocation, initPanelEditor, panelEditorCleanUp, setDiscardChanges, updatePanelEditorUIState, updateTimeZoneForSession, }; const connector = connect(mapStateToProps, mapDispatchToProps); type Props = OwnProps & ConnectedProps<typeof connector>; class PanelEditorUnconnected extends PureComponent<Props> {} export const PanelEditor = connector(PanelEditorUnconnected); ``` For more examples, refer to the [Redux documentation](https://react-redux.js.org/using-react-redux/static-typing#inferring-the-connected-props-automatically).