Reputation: 3041
New to testing mobx with React. I'm testing a a simple side navigation bar, open/closes on hamburger menu. I have set up a store for the Navbar:
export class Store {
toggle = false;
setToggle(bool){
this.toggle = bool;
};
};
decorate(Store, {
toggle: observable,
setToggle: action
});
export default createContext(new Store());
And here is the Navbar component:
export default observer(() => {
const store = useContext(Store); //SideNavStore is imported from mobx store folder
const handleOnClick = () => {
store.setToggle(false);
}
return(
<div data-testid="test">
<Drawer open={store.toggle} onClose={handleOnClick}>
<div role="presentation">
<List>
{routes.map(route => {
return <>
<ListItem button onClick={handleOnClick}>
<ListItemText primary={route.name}/>
</ListItem>
</>
})}
</List>
</div>
</Drawer>
</div>
);
});
This is App.js
export default () => {
return (
<div className="App">
<Navbar ></Navbar>
</div >
)
}
Test.js
describe('Navbar Interaction', () => {
describe('Inpsecting Navbar Contents', () => {
beforeEach(cleanup);
class Store {
sideNavToggle = true;
}
const DecoratedStore = decorate(Store,{
sideNavToggle: observable
});
const renderWithStore = (store) => {
render(
<Navbar />
);
}
it('Expect links are present', () => {
const store = new DecoratedStore();
const { getByText } = renderWithStore(store);
expect(getByText("My Dashboard")).toBeTruthy();
});
});
})
My test here fails because it can't find the text in the document, Drawer Open
is set to false
configured by the store.toggle
. Trying to figure out how to inject the store or dummy store in the test, there are some tutorials about using Provider/Inject but that requires mobx-react
and I believe they are deprecated; I would like to stick with mobx-react-lite
. In renderWithStore
, I'm stuck on how to pass the dummy store in the test. I could pass the store as a props
but I believe that requires provider/inject
which I don't want to do that if necessary. I rather import the store directly in the Navbar component using React.useContext
. I don't see tests using React.useContext
and Mobx Observer
in the web. Has anyone encountered this type of scenario or can you provide a better approach? Also what is the best practice with using React and Mobx stores? Using React-testing-library
for my tests. Your help is appreciated!
Upvotes: 3
Views: 2980
Reputation: 15420
mobx-react-lite
does advice users to prefer React.useContext
over provider/inject.
Take a look at https://mobx-react.js.org/recipes-context
const storeContext = React.createContext<TStore | null>(null)
export const StoreProvider = ({ children }) => {
const store = useLocalStore(createStore)
return <storeContext.Provider value={store}>{children}</storeContext.Provider>
}
As for testing, if you want the component to use custom store or a mock store, you could do it by passing-in the store to StoreProvider. This how Redux users test their components.
export const StoreProvider = ({ store, children }) => {
return <storeContext.Provider value={store}>{children}</storeContext.Provider>
}
Upvotes: 3