[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
});