Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: use testing library on unit tests #13

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

pedrorosarioo
Copy link

@pedrorosarioo pedrorosarioo commented Oct 8, 2021

This PR adds the usage of react native's testing-library module, as well as new test suites for cases of multiple occurrences of search words on textToHighlight property.

Copy link
Contributor

@lucianomlima lucianomlima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only few issues. Good job here! 👏🏼

const { queryByText, toJSON } = render(<HighlightText {...props} />);

for (const word of props.searchWords) {
expect(queryByText(word)).toBeTruthy();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best to use getBy for check existence and queryBy* for check if is missing

Suggested change
expect(queryByText(word)).toBeTruthy();
expect(getByText(word)).toBeTruthy();

ref: https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#using-query-variants-for-anything-except-checking-for-non-existence

Copy link
Author

@pedrorosarioo pedrorosarioo Oct 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, doesn't make any sense to test if the value returned by a getBy... is truthy, since it throws an error when it is not (docs). The reason for an eventual failure would never be because the value is falsy, so we never have to check if a value returned by a get is truthy, that's why we don't have any example of it on docs, neither on Kent C. Dods article. That approach only applies to `queryBy', because it returns null when there is no matches, which is a falsy value... What is wanted here is to check the organization of the elements, thats why we are using queryBy, we don't want to make any manipulation over the element, we are not checking the content, only checking if the library is organizing the components as expected (i.e wrapping the searched words into a single element on DOM).

Copy link
Contributor

@lucianomlima lucianomlima Oct 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's precisely because your test fails that you should use it, this way there is no chance for you to get a false positive. The getBy* queries should always return true, otherwise your test breaks.

Anyway, it's indicated by the creator of the library. Perhaps he deserves some credit for that suggestion. 😅

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you are not thinking about the code. Why would I do a getByText without store or use it for nothing? Sorry it really didn't convince me to check a condition that can not be different, sounds so like an anti-pattern check if something that will alway return a truthy value is doing this 😅

This is not about the creator, I really think he did and does such a good job, maybe you're just making a mistaken interpretation for this situation.

Copy link
Author

@pedrorosarioo pedrorosarioo Oct 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe if I rephrase my question it gets more clear: If the test will always fail before reach the verification (toBeTruthy) when it is not truthy, why would I need to add this verification?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe if I rephrase my question it gets more clear: If the test will always fail before reach the verification if the value is truthy or falsy when it is not truthy, why you I need the verification?

Tests will not fail before reach the verification, will fail because it's impossible to check. The element that was expected to exists, don't exists.

You will check if the component that is expected to be rendered, was really rendered. Check if something that returns true , is really true is only the way to check. Could be checked if returns 1. Will be the same scenario, if not returns what is expected, should be treated as an error.

Imagine a screen where a person can update her data. Is expected to found a submit button, but for some reason, the button is not rendered. Is this an error?
How this scenario impacts user? Can she finishes the data update process?

For me, cases like that shoud be treated as an error and will be the same for the tests.

Copy link
Author

@pedrorosarioo pedrorosarioo Oct 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests will not fail before reach the verification, will fail because it's impossible to check. The element that was expected to exists, don't exists.

Hmmm, I think you're wrong here. This way, the test WILL fail before reach the verification. The get methods already check if the value is truthy or falsy for us, so we don't need to check if the return of a get is truthy again, if it didn't throw error, so it is already truthy. Do a quick test: write a suite to test if some element exists on the DOM. Note that if you use expect(getByText('my-element-label').toBeTruthy(), there is no way for this test to fail because it was expecting a truthy value then received a falsy value. It happens because when javascript try to evaluate getByText('my-element-label') it will throw an error, and it occurs BEFORE the evaluation of the whole expect, because javascript starts evaluating the leaf nodes (in this case, the inner function calls first). Did it make sense for you?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it!

src/__tests__/index.test.js Outdated Show resolved Hide resolved
@sonarcloud
Copy link

sonarcloud bot commented Oct 16, 2021

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
0.0% 0.0% Duplication

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants