Open tedkreutzer96 opened 1 year ago
Maybe not really related to this, but I want to mock the whole usePlacesWidget
function in a test and it is not working, I get the error TypeError: Cannot redefine property: usePlacesWidget
. Maybe the maintainer (@ErrorPro 😉) can explain a bit how we should test our code which uses the methods of the library, like usePlacesWidget
. That would be really helpful!
For me, I'm getting this error while react testing the component (I used usePlaceWidget here)
Error occurs at: (/react-google-autocomplete/lib/usePlacesWidget.js:80:47) I tried to mock the addListener function in testcases at window object like below: window.google = { maps: { Marker: class {}, Map: class { setTilt() {} fitBounds() {} }, LatLngBounds: class {}, LatLng: class {}, places: { Autocomplete: function() { return {addListener: jest.fn()}; }, event: {trigger: jest.fn()}, AutocompleteService: class {}, }, };
NOTE: THIS SOLVES THE ISSUE:- autocompleteRef.current.addListener is not a function
BUT, it makes all other function not functionable, since I mocked only the addListener
How to mock only addListener, but I want other functions under Autocomplete work @ErrorPro please look into this
Maybe not really related to this, but I want to mock the whole
usePlacesWidget
function in a test and it is not working, I get the errorTypeError: Cannot redefine property: usePlacesWidget
. Maybe the maintainer (@ErrorPro 😉) can explain a bit how we should test our code which uses the methods of the library, likeusePlacesWidget
. That would be really helpful!
Still no answer on this?
@ZhanibekZ This is how I ended up testing, that the callback onPlaceSelected
is doing the right thing in my component:
First I wrote a mock widget, which creates an input ref, which just listens on the change handler of the input element:
const useMockPlacesWidget = (props: {
onPlaceSelected: (places: google.maps.places.PlaceResult) => void;
}) => {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (inputRef && inputRef.current) {
// execute the callback on any change event
inputRef.current.addEventListener('change', () =>
props.onPlaceSelected(mockMapsData),
);
}
}, [props]);
return { ref: inputRef };
};
mockMapsData
here is of type google.maps.places.PlaceResult
.
Then I mock the the whole module implementation to return my mock hook (important: this needs to happen outside of any descibe
block in the outmost scope of the test suite):
jest.mock('react-google-autocomplete', () => ({
usePlacesWidget: useMockPlacesWidget,
}));
describe(...
In my react testing library test I can now do something like this:
it(...
const autocomplete = screen.getByTestId('searchbar');
await waitFor(() => {
expect(autocomplete).toBeInTheDocument();
});
// this is enough to fire the callback execution
fireEvent.change(autocomplete);
After that I can assert, if my callback function onPlaceSelected
did the right thing (in my case, set some redux store values).
This is a lot of overhead for a test that might not even be necessary, because I kind of just test the functionality of this library here. Still hope it is helpful for anybody.
@meteohr When testing react code in Jest it's best practice to not test the package. Mocking the hook and testing your integration with the mock is the right approach. Ideally this package would provide instructions on mocking it but ultimately that's up to the developer.
When testing the widget with
jest
in areact
andtypescript
project, I get the following error:TypeError: autocompleteRef.current.setFields is not a function at node_modules/react-google-autocomplete/lib/usePlacesWidget.js:259:31
With this implementation:
What am I doing wrong here? Why would that function be throwing an error when I'm using the component exactly as prescribed?