Reactjs - Bài 16 - Testing - sử dụng TestUtils

Goal

Hôm nay tôi sẽ viết về Reactjs Addons TestUtils trong Reactjs.

TestUtils

http://facebook.github.io/react/docs/test-utils.html

TestUtils là một addon của Reactjs, cung cấp các method để test các React components.

Các mục như Simulate, renderIntoDocument đã viết khá rõ trong link trên. Ở đây tôi chỉ cố gắng demo 2 dạng testing là Assert và Component Testing.

Tôi có dùng lại Source Code bài Addon ReactLink để demo, lý do là nó đã có include sẵn React Addons :).

Bạn hãy chạy đoạn code dưới và xem kết quả nhé.

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv='Content-type' content='text/html; charset=utf-8'>
  5. <title>Basic React TestUtils Testing</title>
  6. </head>
  7. <body>
  8. <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.js"></script>
  9. <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>
  10. <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react-with-addons.js"></script>
  11. <script type="text/jsx">
  12. var Hello = React.createClass({
  13. render: function() {
  14. return (
  15. <div>{this.props.name}</div>
  16. );
  17. }
  18. });
  19. var OnlyMe = React.createClass({
  20. render: function() {
  21. return (
  22. <div>{this.props.name}</div>
  23. );
  24. }
  25. });
  26. var Link = React.createClass({
  27. mixins: [React.addons.LinkedStateMixin],
  28. getInitialState: function() {
  29. return {message: 'Hello!'};
  30. },
  31. handleChange: function(newValue) {
  32. this.setState({message: newValue});
  33. },
  34. render: function() {
  35. var valueLink = {
  36. value: this.state.message,
  37. requestChange: this.handleChange
  38. };
  39. var valueLinkk =this.linkState('message');
  40. return (
  41. <div>
  42. <Hello name="FOO "/>
  43. <Hello name="BAR"/>
  44. <OnlyMe name="OnlyMe"/>
  45. <p className="title">{valueLink.value}</p>
  46. <span className="title">World!</span>
  47. <span className="sub-title">My Name is C.P</span>
  48. <input type="text" valueLink={valueLink} />
  49. </div>
  50. );
  51. }
  52. });
  53. var LinkComponent = React.render(<Link />, document.body);
  54. // TestUtils
  55. var TestUtils = React.addons.TestUtils;
  56. // Assert
  57. document.write("=== Assert Testing Type ===");
  58. //
  59. document.write("<br/>");
  60. document.write("<br/>");
  61. document.write("<b>1.isElement: check if Link is an Element</b>");
  62. document.write("<br/>");
  63. document.write(">>>Result is: ",TestUtils.isElement(<Link />));
  64. //
  65. document.write("<br/>");
  66. document.write("<br/>");
  67. document.write("<b>2.isElementOfType : check if Link is is a ReactElement whose type is of a React componentClass</b>");
  68. document.write("<br/>");
  69. document.write(">>>Result is: ",TestUtils.isElementOfType(<Link />, Link));
  70. //
  71. document.write("<br/>");
  72. document.write("<br/>");
  73. document.write("<b>3.isDOMComponent: check if Link instance is a DOM component (such as a <div> or <span>)</b>");
  74. document.write("<br/>");
  75. document.write(">>>Result is: ",TestUtils.isDOMComponent(LinkComponent));
  76. //
  77. document.write("<br/>");
  78. document.write("<br/>");
  79. document.write("<b>4.isCompositeComponent : check if Link instance is a composite component (created with React.createClass())</b>");
  80. document.write("<br/>");
  81. document.write(">>>Result is: ",TestUtils.isCompositeComponent(LinkComponent));
  82. //
  83. document.write("<br/>");
  84. document.write("<br/>");
  85. document.write("<b>5.isCompositeComponentWithType : check if Link instance is a composite component (created with React.createClass()) whose type is of a React componentClass.</b>");
  86. document.write("<br/>");
  87. document.write(">>>Result is: ",TestUtils.isCompositeComponentWithType(LinkComponent, Link));
  88. //
  89. document.write("<br/>");
  90. document.write("<br/>");
  91. document.write("=== Component Testing Type ===");
  92. document.write("<br/>");
  93. document.write("<b>1.array findAllInRenderedTree(ReactComponent tree, function test)</b>");
  94. document.write("<br/>");
  95. document.write("Traverse all components in tree and accumulate all components where test(component) is true. This is not that useful on its own, but it's used as a primitive for other test utils.");
  96. document.write("<br/>");
  97. document.write(">>> Result is: ",
  98. TestUtils.findAllInRenderedTree(LinkComponent,
  99. function(component) { return component.tagName === "P" }
  100. ).map(function(component){ return component.getDOMNode().textContent })
  101. );
  102. //
  103. document.write("<br/>");
  104. document.write("<br/>");
  105. document.write("<b>2.array scryRenderedDOMComponentsWithClass(ReactComponent tree, string className)</b>");
  106. document.write("<br/>");
  107. document.write("Finds all instances of components in the rendered tree that are DOM components with the class name matching className");
  108. document.write("<br/>");
  109. document.write(">>> Result is: ",TestUtils.scryRenderedDOMComponentsWithClass(LinkComponent,
  110. 'title'
  111. ).map(function(component){ return component.getDOMNode().textContent }));
  112. //
  113. document.write("<br/>");
  114. document.write("<br/>");
  115. document.write("<b>3.ReactComponent findRenderedDOMComponentWithClass(ReactComponent tree, string className)</b>");
  116. document.write("<br/>");
  117. document.write("Like scryRenderedDOMComponentsWithClass() but expects there to be one result, and returns that one result, or throws exception if there is any other number of matches besides one.");
  118. document.write("<br/>");
  119. document.write(">>> Result is: ",TestUtils.findRenderedDOMComponentWithClass(LinkComponent,
  120. 'sub-title'
  121. ).getDOMNode().textContent);
  122. //
  123. document.write("<br/>");
  124. document.write("<br/>");
  125. document.write("<b>4.array scryRenderedDOMComponentsWithTag(ReactComponent tree, string tagName)</b>");
  126. document.write("<br/>");
  127. document.write("Finds all instances of components in the rendered tree that are DOM components with the tag name matching tagName");
  128. document.write("<br/>");
  129. document.write(">>> Result is: ",TestUtils.scryRenderedDOMComponentsWithTag(LinkComponent,
  130. 'span'
  131. ).map(function(component){ return component.getDOMNode().textContent }));
  132. //
  133. document.write("<br/>");
  134. document.write("<br/>");
  135. document.write("<b>5.ReactComponent findRenderedDOMComponentWithTag(ReactComponent tree, string tagName)</b>");
  136. document.write("<br/>");
  137. document.write("Like scryRenderedDOMComponentsWithTag() but expects there to be one result, and returns that one result, or throws exception if there is any other number of matches besides one.");
  138. document.write("<br/>");
  139. document.write(">>> Result is: ",TestUtils.findRenderedDOMComponentWithTag(LinkComponent,
  140. 'p'
  141. ).getDOMNode().textContent);
  142. //
  143. document.write("<br/>");
  144. document.write("<br/>");
  145. document.write("<b>6.array scryRenderedComponentsWithType(ReactComponent tree, function componentClass)</b>");
  146. document.write("<br/>");
  147. document.write("Finds all instances of components with type equal to componentClass");
  148. document.write("<br/>");
  149. document.write(">>> Result is: ",TestUtils.scryRenderedComponentsWithType(LinkComponent,
  150. Hello
  151. ).map(function(component){ return component.getDOMNode().textContent }));
  152. //
  153. document.write("<br/>");
  154. document.write("<br/>");
  155. document.write("<b>7.ReactComponent findRenderedComponentWithType(ReactComponent tree, function componentClass)</b>");
  156. document.write("<br/>");
  157. document.write("Same as scryRenderedComponentsWithType() but expects there to be one result and returns that one result, or throws exception if there is any other number of matches besides one.");
  158. document.write("<br/>");
  159. document.write(">>> Result is: ",TestUtils.findRenderedComponentWithType(LinkComponent,
  160. OnlyMe
  161. ).getDOMNode().textContent);
  162. //
  163. </script>
  164. </body>
  165. </html>