@@ -21,6 +21,10 @@ describe('ReactIncrementalErrorHandling', () => {
2121 ReactNoop = require ( 'react-noop-renderer' ) ;
2222 } ) ;
2323
24+ afterEach ( ( ) => {
25+ jest . unmock ( '../ReactFiberErrorLogger' ) ;
26+ } ) ;
27+
2428 function div ( ...children ) {
2529 children = children . map ( c => ( typeof c === 'string' ? { text : c } : c ) ) ;
2630 return { type : 'div' , children, prop : undefined } ;
@@ -952,49 +956,22 @@ describe('ReactIncrementalErrorHandling', () => {
952956 } ) ;
953957
954958 describe ( 'ReactFiberErrorLogger' , ( ) => {
955- function initReactFiberErrorLoggerMock ( mock ) {
956- jest . resetModules ( ) ;
957- if ( mock ) {
958- jest . mock ( '../ReactFiberErrorLogger' ) ;
959- } else {
960- jest . unmock ( '../ReactFiberErrorLogger' ) ;
961- }
962- React = require ( 'react' ) ;
963- ReactNoop = require ( 'react-noop-renderer' ) ;
964- }
965-
966- beforeEach ( ( ) => {
967- // Assert that we're mocking this file by default.
968- // If this ever changes, we'll need to update this test suite anyway.
969- expect (
970- require ( '../ReactFiberErrorLogger' ) . logCapturedError . _isMockFunction ,
971- ) . toBe ( true ) ;
972- } ) ;
973-
974- afterEach ( ( ) => {
975- // Restore the default (we verified it was being mocked in beforeEach).
976- jest . mock ( '../ReactFiberErrorLogger' ) ;
977- } ) ;
978-
979959 function normalizeCodeLocInfo ( str ) {
980960 return str && str . replace ( / \( a t .+ ?: \d + \) / g, '(at **)' ) ;
981961 }
982962
983963 it ( 'should log errors that occur during the begin phase' , ( ) => {
984- initReactFiberErrorLoggerMock ( false ) ;
985964 // Intentionally spy in production too.
986- // TODO: It is confusing how these tests correctly "see" console.error()s
987- // from exceptions becase they called initReactFiberErrorLoggerMock(false)
988- // and thus unmocked the error logger. It is globally mocked in all other
989- // tests. We did this to silence warnings from intentionally caught errors
990- // in tests. But perhaps we should instead make a pass through all tests,
991- // intentionally assert console.error() is always called for uncaught
992- // exceptions, and then remove the global mock of ReactFiberErrorLogger.
993965 spyOn ( console , 'error' ) ;
994966
995967 class ErrorThrowingComponent extends React . Component {
996968 componentWillMount ( ) {
997- throw Error ( 'componentWillMount error' ) ;
969+ const error = new Error ( 'componentWillMount error' ) ;
970+ // Note: it's `true` on the Error prototype our test environment.
971+ // That lets us avoid asserting on warnings for each expected error.
972+ // Here we intentionally shadow it to test logging, like in real apps.
973+ error . suppressReactErrorLogging = undefined ;
974+ throw error ;
998975 }
999976 render ( ) {
1000977 return < div /> ;
@@ -1030,19 +1007,17 @@ describe('ReactIncrementalErrorHandling', () => {
10301007 } ) ;
10311008
10321009 it ( 'should log errors that occur during the commit phase' , ( ) => {
1033- initReactFiberErrorLoggerMock ( false ) ;
1034- // TODO: It is confusing how these tests correctly "see" console.error()s
1035- // from exceptions becase they called initReactFiberErrorLoggerMock(false)
1036- // and thus unmocked the error logger. It is globally mocked in all other
1037- // tests. We did this to silence warnings from intentionally caught errors
1038- // in tests. But perhaps we should instead make a pass through all tests,
1039- // intentionally assert console.error() is always called for uncaught
1040- // exceptions, and then remove the global mock of ReactFiberErrorLogger.
1010+ // Intentionally spy in production too.
10411011 spyOn ( console , 'error' ) ;
10421012
10431013 class ErrorThrowingComponent extends React . Component {
10441014 componentDidMount ( ) {
1045- throw Error ( 'componentDidMount error' ) ;
1015+ const error = new Error ( 'componentDidMount error' ) ;
1016+ // Note: it's `true` on the Error prototype our test environment.
1017+ // That lets us avoid asserting on warnings for each expected error.
1018+ // Here we intentionally shadow it to test logging, like in real apps.
1019+ error . suppressReactErrorLogging = undefined ;
1020+ throw error ;
10461021 }
10471022 render ( ) {
10481023 return < div /> ;
@@ -1078,18 +1053,16 @@ describe('ReactIncrementalErrorHandling', () => {
10781053 } ) ;
10791054
10801055 it ( 'should ignore errors thrown in log method to prevent cycle' , ( ) => {
1081- initReactFiberErrorLoggerMock ( true ) ;
1056+ jest . resetModules ( ) ;
1057+ jest . mock ( '../ReactFiberErrorLogger' ) ;
1058+ React = require ( 'react' ) ;
1059+ ReactNoop = require ( 'react-noop-renderer' ) ;
10821060 // Intentionally spy in production too.
1083- // Note: we're seeing console.error() even though ReactFiberErrorLogger is
1084- // mocked because we're currently testing the console.error() call inside
1085- // ReactFiberScheduler (for cycles). It doesn't get affected by mocking.
1086- // TODO: mocking is confusing and we should simplify this and remove
1087- // special cases.
10881061 spyOn ( console , 'error' ) ;
10891062
10901063 class ErrorThrowingComponent extends React . Component {
10911064 render ( ) {
1092- throw Error ( 'render error' ) ;
1065+ throw new Error ( 'render error' ) ;
10931066 }
10941067 }
10951068
@@ -1099,7 +1072,12 @@ describe('ReactIncrementalErrorHandling', () => {
10991072 ReactFiberErrorLogger . logCapturedError . mockImplementation (
11001073 capturedError => {
11011074 logCapturedErrorCalls . push ( capturedError ) ;
1102- throw Error ( 'logCapturedError error' ) ;
1075+ const error = new Error ( 'logCapturedError error' ) ;
1076+ // Note: it's `true` on the Error prototype our test environment.
1077+ // That lets us avoid asserting on warnings for each expected error.
1078+ // Here we intentionally shadow it to test logging, like in real apps.
1079+ error . suppressReactErrorLogging = undefined ;
1080+ throw error ;
11031081 } ,
11041082 ) ;
11051083
@@ -1124,14 +1102,7 @@ describe('ReactIncrementalErrorHandling', () => {
11241102 } ) ;
11251103
11261104 it ( 'should relay info about error boundary and retry attempts if applicable' , ( ) => {
1127- initReactFiberErrorLoggerMock ( false ) ;
1128- // TODO: It is confusing how these tests correctly "see" console.error()s
1129- // from exceptions becase they called initReactFiberErrorLoggerMock(false)
1130- // and thus unmocked the error logger. It is globally mocked in all other
1131- // tests. We did this to silence warnings from intentionally caught errors
1132- // in tests. But perhaps we should instead make a pass through all tests,
1133- // intentionally assert console.error() is always called for uncaught
1134- // exceptions, and then remove the global mock of ReactFiberErrorLogger.
1105+ // Intentionally spy in production too.
11351106 spyOn ( console , 'error' ) ;
11361107
11371108 class ParentComponent extends React . Component {
@@ -1155,7 +1126,12 @@ describe('ReactIncrementalErrorHandling', () => {
11551126
11561127 class ErrorThrowingComponent extends React . Component {
11571128 componentDidMount ( ) {
1158- throw Error ( 'componentDidMount error' ) ;
1129+ const error = new Error ( 'componentDidMount error' ) ;
1130+ // Note: it's `true` on the Error prototype our test environment.
1131+ // That lets us avoid asserting on warnings for each expected error.
1132+ // Here we intentionally shadow it to test logging, like in real apps.
1133+ error . suppressReactErrorLogging = undefined ;
1134+ throw error ;
11591135 }
11601136 render ( ) {
11611137 renderAttempts ++ ;
0 commit comments