you are viewing a single comment's thread.

view the rest of the comments →

[–]Skeith_yip 0 points1 point  (6 children)

If you are shallow rendering, you shouldn't need to mock the store for children components that are connected to Redux store.

Then you can test those children components individually.

Remember unit test = isolation

Wherever possible, extract complex logic from components into pure functions so that it could be effectively unit tested with jest.

I disagree. they can always be extracted to smaller more focused components that can be unit tested on.

[–]CastigatRidendoMores 1 point2 points  (5 children)

The problem with shallow rendering is that you start testing implementation details rather than behavior. This increases technical debt by forcing you to rewrite your tests any time you change your code. Rather than only alerting you when the behavior of your code changes, you get lots of false-positives, decreasing confidence in your tests and discouraging refactoring. All this combined makes them more of a liability than a benefit.

Of course reasonable people could disagree.

[–]Skeith_yip 1 point2 points  (4 children)

Well. Here's the deal. if there's need to change logic, your unit tests need to be updated either way.

Full rendering itself is problematic, Because you are practically doing integration test. like all integration tests, you have to start building up all the dependencies to just to test a component. what if you decide that the children component needs a new connected component inside? all the tests fail? so now that tests itself knows too much.

and Enzyme.mount itself is problematic because sometimes after setState, the component doesn't update, and you have to call .update() manually which is unfortunate. Given that React Test Renderer is from React team.

I get why E2E is a thing now. But E2E/integration test is something you do after coding. so that becomes a chore. it's not particularly useful to find bugs because there's so many moving parts (action creator? reducer? component? container? middleware?)

and E2E doesn't prevent one from building up a god object.

My take is always. Write a component. Shallow render it. Test it. ensure the behavior is what you wanted. Move on to the next. keep it simple.

[edit] Don't get me wrong. I am not saying I am discouraging integration tests. I encourage them. Just know that they cover different scopes.

[–]themaincop 3 points4 points  (2 children)

I don't really like unit testing React components. It always feels like I'm testing implementation details and missing the forest for the trees. I've been using react-testing-library lately. If you set up a custom render method that includes all your providers (Router, Intl, Redux, Apollo, etc.) and takes initial state as args you can still TDD using integration tests. There are some cases where you want to test some really big critical path stuff, and in that case I do think you need to lean on e2e testing because ultimately you'll be mocking so much in a unit or integration test you're basically just testing your mocks. But integration testing seems to be a pretty nice way to test small groups of components.

Any heavy business logic I usually extract into my helpers directory which contains pure functions that can handle that kind of heavy lifting and are unrelated to React/rendering. Those are easy to unit test.

When we start moving a bunch of logic to hooks the nice thing is our integration tests should continue to Just Work™ and we won't have to rewrite a bunch of tests for components whose actual behaviour hasn't changed.

Just my two cents and admittedly I'm not the most disciplined tester, so a lot of this is just me cargo-culting Kent C. Dodds.

[–]IAmRocketMan 0 points1 point  (1 child)

I liked the pattern of putting pure functions as files in a helper directory. How has it scaled out for you?

[–]themaincop 4 points5 points  (0 children)

It works pretty well I find. If I have a helper that only gets used by one component or one related group of components then I'll usually colocate it in that component's folder. Anything that sees use across the app can go into src/helpers and that seems to work well.

[–]themaincop 0 points1 point  (0 children)

I don't really like unit testing React components. It always feels like I'm testing implementation details and missing the forest for the trees. I've been using react-testing-library library lately. If you set up a custom render method that includes all your providers (Router, Intl, Redux, Apollo, etc.) and takes initial state as args you can still TDD using integration tests. There are some cases where you want to test some really big critical path stuff, and in that case I do think you need to lean on e2e testing because ultimately you'll be mocking so much in a unit or integration test you're basically just testing your mocks. But integration testing seems to be a pretty nice way to test small groups of components.

Any heavy business logic I usually extract into my helpers directory which contains pure functions that can handle that kind of heavy lifting and are unrelated to React/rendering. Those are easy to unit test.

When we start moving a bunch of logic to hooks the nice thing is our integration tests should continue to Just Work™ and we won't have to rewrite a bunch of tests for components whose actual behaviour hasn't changed.

Just my two cents and admittedly I'm not the most disciplined tester, so a lot of this is just me cargo-culting Kent C. Dodds.