Why do I get the error "Received value must be an HTMLElement or an SVGElement" when using react-native?
Asked Answered
M

3

24

I'm new to unit testing and I'm trying to render a component to learn more about the library.

I'm trying to follow this guide.

Component

<TouchableOpacity
    style={style}
    onPress={onPress}
    accessibilityRole="button"
>
    <AppText style={textStyle}>{title.toUpperCase()}</AppText>
</TouchableOpacity> 

Test

it("Has the correct title in the button", () => {
    const { getByText } = render(<AppButton title="Hello" />);
  
    expect(getByText("HELLO")).toBeInTheDocument();
});

I'm simply trying to see that the component renders correctly but I get the error

received value must be an HTMLElement or an SVGElement.
    Received has type:  object
    Received has value: {"_fiber": {"_debugHookTypes": null, "_debugID": 40, "_debugIsCurrentlyTiming": false, "_debugNeedsRemount": false, "_debugOwner": [FiberNode], "_debugSource": null, "actualDuration": 0, "actualStartTime": -1, "alternate": null, "child": [FiberNode], "childExpirationTime": 0, "dependencies": null, "effectTag": 1, "elementType": [Function Component], "expirationTime": 0, "firstEffect": null, "index": 0, "key": null, "lastEffect": null, "memoizedProps": [Object], "memoizedState": null, "mode": 0, "nextEffect": null, "pendingProps": [Object], "ref": null, "return": [FiberNode], "selfBaseDuration": 0, "sibling": null, "stateNode": [Component], "tag": 1, "treeBaseDuration": 0, "type": [Function Component], "updateQueue": [Object]}}

Any advice on what I'm doing wrong?

Material answered 7/3, 2021 at 12:8 Comment(4)
Hey, I'm using react-native-testing-library :)Material
I used testID and it's working as expected :)Material
Here is the working solution, it works if I access by testID. it("Has the correct title in the button", () => { const { getByTestId } = render(<AppButton title="Hello" />); const eins = getByTestId("text"); expect(eins.children[0]).toEqual("HELLO"); }); Although it'd have been good to understand why I couldn't get the value with getByText, at least it's working. :)Material
In case anybody did the dumb thing that I did and stumbles upon this answer, I was using findBy which returns a promise - await expect(findBy(...)).resolves.toBeInTheDocument()Hyp
F
32

You can use waitFor

Sample:

import { waitFor } from "@testing-library/react-native";


waitFor(() => expect(getByText("Your-text")).toBeInTheDocument());

// or

waitFor(() => expect(getByTestId("Your-Test-Id")).toBeInTheDocument());
Freddafreddi answered 8/11, 2021 at 10:13 Comment(5)
waitFor works!!Inflatable
I am using MDX for React. waitFor resolved the issue. ThanksIntermezzo
Note that waitFor() is async, so your tests should await waitFor(() => expect(getByText("Your-text")).toBeInTheDocument());Flashgun
waitFor works by await waitFor throws errorComprise
expect( screen.getByLabelText("testdata")).toBeInTheDocument(); worked for me.Rebekahrebekkah
A
19

The issue is that you're trying to use the toBeInTheDocument helper function from @testing-library/jest-dom with React Native code. @testing-library/jest-dom expects DOM elements to be passed to its functions, and is meant to be used with @testing-library/react instead - it won't work with the native elements from React Native.

When using @testing-library/react-native you can assert the presence of an element like so.

it("has the correct title in the button", () => {
    const { getByText } = render(<AppButton title="Hello" />);
    expect(getByText("HELLO")).toBeTruthy();
});
Archivist answered 8/11, 2021 at 23:21 Comment(1)
Thanks! I was doing the same mistake on not using testing lib methodsTownspeople
F
2

whoever stumbles over this answer when searching for this error:

received value must be an htmlelement or an svgelement. 
received has type: object 
received has value: {}

I misused findByText and getByText.

so when I would wrap my findByText with a waitFor my tests succeeded, but they always succeeded no matter what I tested for. so just wrapping it with a waitFor might look like it solved the issue but actually you are not testing what you want.

the error indicates that the findByText returns a promise therefore the test fails because it wants an HTMLElement.

Ferromagnetism answered 19/12, 2023 at 15:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.