{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "@id": "https://www.vidyasource.com/blog/lessons-java-testing-react/",
  "url": "https://www.vidyasource.com/blog/lessons-java-testing-react/",
  "mainEntityOfPage": "https://www.vidyasource.com/blog/lessons-java-testing-react/",
  "headline": "Lessons from Java for Testing in React",
  "description": "See how years of testing in Java have taught us lessons you can apply to improve your testing in React.",
  "datePublished": "2018-10-21T00:00:00.000Z",
  "author": {
    "@type": "Person",
    "name": "Neil Chaudhuri",
    "jobTitle": "President",
    "url": "https://www.linkedin.com/in/neil-chaudhuri/",
    "sameAs": "https://www.linkedin.com/in/neil-chaudhuri/"
  },
  "publisher": {
    "@id": "https://www.vidyasource.com/#organization"
  },
  "image": "https://www.vidyasource.com/img/blog/react.png",
  "keywords": [
    "React",
    "JavaScript",
    "Java",
    "TypeScript",
    "Elm",
    "Webpack",
    "RxJS",
    "ImmutableJS",
    "JUnit",
    "Agile",
    "Software Engineering",
    "Programming",
    "Testing",
    "Continuous Integration"
  ],
  "articleBody": "Have you found that your code has a lot of bugs even though you've invested in maintaining 90% code coverage? Have you also\nfound that your tests break so often that you don't want to write any more?\n\nI have. With multiple clients.\n\nPart of the problem is [code coverage is a misleading indicator of quality](http://blog.codepipes.com/testing/software-testing-antipatterns.html#anti-pattern-6---paying-excessive-attention-to-test-coverage).\nEven worse, you are writing tests that don't test anything except the implementation details of your code. That's almost worse than writing no tests\nat all.\n\nThis has really hit me as I learn to write tests for React. My career has been built primarily on Java,\nScala, Ruby, and Python--*i.e.* backend development.\nOver the years I have written a lot of JavaScript too, but we are taking it to the next level and enduring some growing pains as\nwe migrate the front end of a [Scala application we built for a client](https://www.vidyasource.com/case-studies/casting-platform-nina-day/) to React\n(with all the trimmings--Webpack, TypeScript, RxJS, Immutable.js, *etc.*).\nReact is spearheaded by Facebook and fortified by a vibrant community, so I assumed a consensus on patterns and practices.\n\nNope!\n\n*How do you reuse code in React?*\nReact developers will endorse anything from  [mixins to higher-order components to render props](https://www.richardkotze.com/coding/hoc-vs-render-props-react).\n\n*How do you manage complex state in React?*\nReact developers will endorse anything from\n[Flux to Redux to MobX](https://codeburst.io/mobx-vs-redux-with-react-a-noobs-comparison-and-questions-382ba340be09) to\nsimply [RxJS](https://news.ycombinator.com/item?id=15625858).\n\nI've even seen things get contentious. We are approaching the point where magazines advise couples on first dates\nto avoid discussing politics, religion, and React state management preferences.\n\nTesting in React is no different--no consensus on \"best practices.\" Luckily though my experience testing on the server\noffers insight that significantly clarifies things for me.\n\n## Kent Saves Us When Superman Can't\n\nYou will find that one consistent voice of reason emerging from the cacophony of React advice is\n[Kent C. Dodds](https://blog.kentcdodds.com/) (KCD), Paypal engineer and React expert. The Notorious KCD is\nthe new \"[King of All Media](https://en.wikipedia.org/wiki/Howard_Stern)\" with great content on his blog, at conferences,\non podcasts, and all over social media.\n\nI have found KCD's insights particularly useful in the area of React testing, and I recently came across his\n[commentary on \"shallow rendering,\"](https://blog.kentcdodds.com/why-i-never-use-shallow-rendering-c08851a68bb7) a popular\ntesting paradigm in the React community. Like pretty much everything else in React, shallow rendering is controversial,\nand KCD did not mince words in expressing his disdain for it. His take is a corollary of his even more controversial take that\n[most tests should be integration tests](https://blog.kentcdodds.com/write-tests-not-too-many-mostly-integration-5e8c7fff591c).\n\nIt turns out I agree with KCD on shallow rendering, but I come to the same conclusion via an entirely different rationale\nbased on my experience with testing on the server. Please take a moment and read KCD's posts so you can understand shallow\nrendering, his sample code, and his rationale as it relates to the distinction between unit and integration testing.\n\nTake your time. [I'll wait](https://www.youtube.com/watch?v=E3iVVCttwPw).\n\n## Lessons from Java\n\nAs you see in his post, KCD's example focuses on a `HiddenMessage` component that contains a `Fade` component that in turn\ncontains a `CSSTransition` component. A test based on shallow rendering would essentially \"turn off\" `Fade` and\n`CSSTransition`, and KCD maintains that makes the test pointless because it yields both false positives and false negatives.\nIt does nothing to confirm the quality of `HiddenMessage`. Instead, he argues \"unit testing\" that only\nrenders the top-level component should be\nreplaced with \"integration testing\" where the top-level component is rendered with [Jest](https://jestjs.io/en/)\nmocks of its internal components.\n\nI completely agree with KCD that shallow rendering is useless but for a completely different reason. We can look to Java\nfor insight. Here is an analogous implementation of `HiddenMessage` in Java.\n\n~~~java \npublic class HiddenMessage extends Component {\n  private boolean show = false;\n  private Fade fade;\n  \n  public HiddenMessage(Children children, Props props) {\n    fade = new Fade(children, props);\n  }\n  \n  public void toggle() {\n    this.show = !this.show;\n  }\n  \n  public String render() {\n    return\n      \"<div>\n        <button onClick={\" + this.toggle() + \">Toggle</button>\" + \n        fade.render() +\n      \"</div>\";\n  }\n  \n  public static class Fade extends Component {\n    private CSSTransition cssTransition;\n    \n    public Fade(Children children, Props props) {\n      cssTransition = new CssTransition(children, props, 1000, \"fade\");\n    }\n    \n    public String render() {\n      return cssTransition.render();\n    } \n  }\n  \n  public static class CSSTransition extends Component {\n    private Children children;\n    private Props props;\n    private int timeout;\n    private String className;\n    \n    public CSSTransition(Children children, Props props, int timeout, String className) {\n      this.children = children;\n      this.props = props;\n      this.timeout = timeout;\n      this.className = className;\n    }\n    \n    public String render() {\n      return \n        \"<CSSTransition\" + \" \" +  props + \" \" + timeout + \" \" + className + \">\" + children + \"</CSSTransition>\"\n    }\n  }\n}\n~~~\n\nI would say this faithfully represents the relationship among the three components albeit with Java idioms. `Fade` and\n`CSSTransition` only exist within the context of `HiddenMessage`. Clients have no direct access to those internal components.\nThe components themselves are therefore defined as `private static` classes within `HiddenMessage`; instances are marked `private`\nwithin `HiddenMessage`.\n\nA quick aside: *I recognize that this makes for unorthodox Java code, but the goal here is to reflect the intent of the\nReact component `HiddenMessage` as accurately as possible in a \"Java way.\"*\n\nNow look at this and imagine a test for `HiddenMessage` where `Fade` and `CSSTransition` are disabled into no-ops. All you do is render\na button that proves you can toggle a flag. [Who cares?](http://i.qkme.me/3q4n8o.jpg).\nThere is so much more to `HiddenMessage` we never explore. Such a test offers no insight into\nwhether `HiddenMessage` really works.\n\nSo yes, it is pretty clear shallow rendering is not helpful just as KCD argues.\n\nBut for him, this is proof that [Guillermo Rauch was right all along](https://twitter.com/rauchg/status/807626710350839808):\n\"integration testing\" beats \"unit testing.\"\n\nFor me, the key insight I gleaned from looking at the Java analogue of `HiddenMessage` is not about the dichotomy\nbetween unit and integration testing, a\n[controversy fraught with baggage](https://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-test/4904533#4904533)\nbecause no one can even agree on how we define those terms to begin the conversation, but about why we test at all.\n\nWe write tests because we want to create something like a lab experiment--a controlled environment where we see how our code\nbehaves when it is exercised just as clients will in production. It is a precondition that your code is initialized to some \"ready state\"\nso it can satisfy the public API contract it has with its clients. In Java, you typically accomplish that\nwith a constructor (that may throw `IllegalArgumentException` if necessary) into which mock or stub dependencies are injected\nin test code to achieve the control we need--though [some say that's a smell in itself](https://www.youtube.com/watch?v=EaxDl5NPuCA).\n\nIn the Java version of `HiddenMessage`, you have to\n[work a little harder to mock the dependencies](https://stackoverflow.com/questions/36173947/mockito-mock-private-field-initialization)\nbecause they are private implementation details. Most Java developers would correctly find this awkward and smelly, but any\n`HiddenMessage` test is worthless if it isn't supplied the tools it needs one way or another to satisfy its API contract.\nShallow rendering fails because it eschews this basic concept--not because it proves\nintegration tests beat unit tests.\n\n## So what now?\n\nThe whole point of mocks and stubs is to supply the code you're testing with dependencies it needs to fulfill its contract\nin a way that's deterministic so we have the control and predictability every experiment needs. Applying idioms from testing\nin Java can inspire you to consider any combination of these approaches for testing in React:\n\n* Use Jest as KCD recommends to mock components and side effects like REST calls just as a Java\ndeveloper uses Mockito.\n* Use props to mimic constructor injection of mocked or stubbed dependencies. In fact, [render props](https://reactjs.org/docs/render-props.html),\nwhich are now *en vogue* for sharing React components, essentially enable constructor injection of components. You can supply\nany component you want to a render prop in your test.\n* [Use the functional nature of JavaScript to your advantage](https://www.vidyasource.com/blog/the-business-case-for-functional-programming/) in testing.\nFor example, REST calls are the most common side effects in JavaScript programming,\nand using TypeScript you could have a function prop `fetch: (s: string) => Promise<string>` to represent a REST call returning JSON.\nIn your test, you supply a stubbed implementation like `(s: string) => { Promise.resolve({id: 5}) }` while your\nproduction code supplies a function with the same shape that makes real REST calls. This is analogous in Java to having a\nconstructor parameter of type `Function<String, CompletableFuture<String>>` that you stub with\n`(s) -> CompletableFuture.completedFuture({id: 5})` in your JUnit tests. In either case, no mocking library is needed.\n\nOr...moving away from Java, stop being scared and\n[embrace the Haskell-like idioms in Elm](https://package.elm-lang.org/packages/ryanolsonx/elm-mock-http/latest/).\n\nI prefer eschewing a third-party mocking library. For one thing, that's one less\ndependency. More importantly, it makes your tests more durable as you avoid expectations about the implementation details\nof your component, which will change all the time. Focus on the intent of your code and its collaborators rather than the inner workings.\n\nDon't mistake a preference for a rule though. Despite the [absolutist language](https://www.youtube.com/watch?v=wgpytjlW5wU)\nin many programming blog posts out there, each approach has pros and cons. Nothing is all good or all bad. Keep all\nthese options on the table--even the shallow rendering and [snapshot testing](https://jestjs.io/docs/en/snapshot-testing) that neither KCD nor I really likes,\nand choose the one that balances the time it takes to write a test with your level of confidence in the quality and\ndurability of the outcome. You will likely find a blend of these approaches works best.\n\n## Conclusion\n\nIt's great to see we have evolved from debating whether testing is necessary to debating how best to do it. As full stack\nengineers--equally adept at building efficient services as elegant user interfaces--become more common, it makes sense\nto leverage knowledge across domains. I'm no expert at testing in React, and I welcome the opportunity to integrate as much as I can from\nexperts like KCD with my own experience testing on the server in languages like Java where we have tackled many of the same\nissues. I hope to see for myself which strategies work best to solve various problems in testing in React.\n\nThere will always be debate. If nothing else, let's agree to focus on API contracts rather than implementation details and\nkeep things simple so we don't lose as many weekends refactoring tests every time a client wants a new feature."
}