@samitouri / QOS-React / commits / 1107b9673c

[TestUtils.act] warn when using TestUtils.act in node (#14768)

* warn when using TestUtils.act in node * s/warns/throws * s/throw/warn * consistent ellipses

Sunil Pai committed Feb 6, 2019 at 16:25 UTC 1107b9673c779425a251ed5336ee8b6721498666
2 files changed +34 -4
packages/react-dom/src/test-utils/ReactTestUtils.js
+19 -3
@@ -151,8 +151,8 @@ function validateClassInstance(inst, methodName) {
151 );
152 }
153
154 -// stub element used by act() when flushing effects
155 -let actContainerElement = document.createElement('div');
154 +// a stub element, lazily initialized, used by act() when flushing effects
155 +let actContainerElement = null;
156
157 /**
158 * Utilities for making it easy to test React components.
@@ -391,9 +391,25 @@ const ReactTestUtils = {
391 SimulateNative: {},
392
393 act(callback: () => void): Thenable {
394 + if (actContainerElement === null) {
395 + // warn if we can't actually create the stub element
396 + if (__DEV__) {
397 + warningWithoutStack(
398 + typeof document !== 'undefined' &&
399 + document !== null &&
400 + typeof document.createElement === 'function',
401 + 'It looks like you called TestUtils.act(...) in a non-browser environment. ' +
402 + "If you're using TestRenderer for your tests, you should call " +
403 + 'TestRenderer.act(...) instead of TestUtils.act(...).',
404 + );
405 + }
406 + // then make it
407 + actContainerElement = document.createElement('div');
408 + }
409 +
410 + const result = ReactDOM.unstable_batchedUpdates(callback);
411 // note: keep these warning messages in sync with
412 // createReactNoop.js and ReactTestRenderer.js
396 - const result = ReactDOM.unstable_batchedUpdates(callback);
413 if (__DEV__) {
414 if (result !== undefined) {
415 let addendum;
packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.internal.js
+15 -1
@@ -1023,7 +1023,7 @@ describe('ReactTestRenderer', () => {
1023 });
1024
1025 describe('act', () => {
1026 - it('works', () => {
1026 + it('can use .act() to batch updates and effects', () => {
1027 function App(props) {
1028 React.useEffect(() => {
1029 props.callback();
@@ -1043,5 +1043,19 @@ describe('ReactTestRenderer', () => {
1043
1044 expect(called).toBe(true);
1045 });
1046 + it('warns and throws if you use TestUtils.act instead of TestRenderer.act in node', () => {
1047 + // we warn when you try to load 2 renderers in the same 'scope'
1048 + // so as suggested, we call resetModules() to carry on with the test
1049 + jest.resetModules();
1050 + const {act} = require('react-dom/test-utils');
1051 + expect(() => {
1052 + expect(() => act(() => {})).toThrow('document is not defined');
1053 + }).toWarnDev(
1054 + [
1055 + 'It looks like you called TestUtils.act(...) in a non-browser environment',
1056 + ],
1057 + {withoutStack: 1},
1058 + );
1059 + });
1060 });
1061 });