Still having issues to unit test connected components
danielmariz opened this issue · comments
So I was following the hooks test examples
but sill don't get the proper approach to write unit test for connected components.
On logic's unit test everything works fine but inside the connected component the values just won't change based on action/listeners calls.
my current code is in Typescript but here's a simple example for what I'm trying to achieve:
const logic = kea({
path: ['containers', 'user', 'main'],
actions: {
requestUserData: () => null,
setUserData: (data) => ({ data }),
userDataFailed : (message) => ({ message }),
},
reducers: {
isLoading: [false, {
requestUserData: () => true,
setUserData: () => false,
userDataFailed: () => false,
}]
},
listeners: ({ actions }) => ({
requestUserData: async () => {
try {
const {payload} = await getUser() //api call
actions.setUserData(payload)
} catch (error) {
actions.userDataFailed(error.message)
}
},
})
})
const MyComponent = () => {
const {isLoading} = useValues(logic)
const {requestUserData} = useActions(logic)
return <>
{isLoading && <Loader data-testid='loader' />}
<button onClick={() => requestUserData()}>click</button>
</>
}
beforeEach(() => {
resetContext({
// createStore: true,
createStore: {
paths: ['kea', 'pages', 'containers'],
},
plugins: [
waitForPlugin,
]
})
})
test('should show a loader when user clicks de button', async () => {
const getUserMock = getUser as jest.Mock
getUserMock.mockImplementationOnce(() => Promise.resolve({payload: {...something}}))
render(<Provider store={getContext().store}>
<MyComponent />
</Provider>)
fireEvent.click(getByText('click'))
await waitFor(async () => {
// EXPECT THIS TO HAPPEN
expect(screen.getByTestId('loader')).toBeInTheDocument()
await waitForElementToBeRemoved(() => screen.getByTestId('loader'))
})
})
So this test triggers the listeners but won't change the reducer value so the loader will never been shown in the test render
Any help how to get this working?
I'm keen to write an exemple for the documentation and do a PR later
Cheers
Hey, finally coming back to this... and I'm having trouble understanding your code. There's no waitFor
function the way you have it in your code sample. There's waitForAction
, which could be used instead, but in this case, I assume since your mock returns immediately, there's just no time to show the loader.
Is this an issue you're still struggling with?