Jest: Error when trying to import Native Modules; unable to prevent with Mock












0















I've recently been brought on to a team as Test Engineer and I'm trying to get Jest unit tests up and running on our React Native app. My predecessor has already authored dozens of unit tests, most of which are not running successfully.



I'm getting the following error when running npm test



 FAIL  __tests__/index.test.js
● Test suite failed to run

TypeError: Cannot read property '_addDeviceToGroup' of undefined

4 | } from 'react-native';
5 | const {
> 6 | _addDeviceToGroup,
| ^
7 | } = NativeModules._BleAssociator
8 | const {
9 | _queryName,

at Object._addDeviceToGroup (app/utils/mesh.js:6:3)
at Object.<anonymous> (app/actions/hierarchy.js:26:1)
at Object.<anonymous> (app/actions/organizations.js:14:1)


It seems as though the issue arose when we implemented custom Native Modules written by our backend team (again, before my joining the team).



After some research, I decided to proceed under the assumption that this has to do with Jest's inability to parse the Objective-C in the Engine that's feeding in the Native Modules and not some issue with our stack (happy to consider that possibility, though).



I've reviewed the Jest documentation, combing specifically through a couple relevant documents (Mock Functions, Using Jest with ES Module Imports, Testing Native Modules with Jest Mock, React Native Modules Guide)



My issue appears to be identical to this issue; however, the fix is not working for me. Even when mocking the NativeModules, I get the same error.



I've become familiar with the notion that Jest mocks are hoisted above the import statements, but it's not clear to me why the mocks are in the describe block in the issue I linked above (other than maybe to reset the mock function for each new test in case so as to not confound the .mock property's return data... I digress).



To me, it seems the error is occurring during the imports, before any of the code is executed. To test this, I've gone back and forth, commenting out everything but the import statements and the mocks. Doing this, I still get the same error. This is also the case when I use a beforeEach() mocha statement, as in the solution to the issue linked above.



The only thing that fixes this error commenting out the imports altogether.



I have not tried error handling (try/catch), as I'm not certain how I could still successfully import the component I'm testing if the catch block is executed.



Sorry for all that background. I have spent a couple workdays on this, so I want to make certain all my bases are covered.



Here's an example test:



/__tests__/app/components/Onboarding/Splash/Splash.test.js






import {
NativeModules,
} from 'react-native';

import { Splash } from '../../../../../app/components/Onboarding/Splash/Splash.js';
// import login from '../../../../../app/actions/login';

// NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
// login = jest.fn;

export default function({React, shallow}) {

const props = {
// some test props
};

function make({navigation, getUserInfo, verifyUser, login} = props) {
return shallow(
// renders the component with props
);
}

describe('<Splash />', () => {
// I added this part (didn't help)
beforeEach(() => {
NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
login = jest.fn;
});
// end part I added

// stuff (all the tests are in here)

});

}





The NativeModules and login imports, the commented out lines, and the beforeEach() block are things I've tried intermittently to no avail.



When trying to trace this error, I found that commenting out import statement in the original Splash.js that run scripts (as ES6 import runs the script it references) that try to import NativeModules fixes the error I see. As you might have gleaned from the stack trace, these go many levels deep.



PHEW. If you've read this far, I really appreciate the help.



Sorry to have such a long and complicated question. As you can see, we have a large and convoluted stack. It's possible the fix from the issue above isn't working because of how many chained imports happen before getting to the error.



I'd love it if it's a tiny fix that I'm missing or if there was some sort of "shallow"-ish import that I'm not aware of.



Thanks a bajillion for your help. Any input is welcome.










share|improve this question





























    0















    I've recently been brought on to a team as Test Engineer and I'm trying to get Jest unit tests up and running on our React Native app. My predecessor has already authored dozens of unit tests, most of which are not running successfully.



    I'm getting the following error when running npm test



     FAIL  __tests__/index.test.js
    ● Test suite failed to run

    TypeError: Cannot read property '_addDeviceToGroup' of undefined

    4 | } from 'react-native';
    5 | const {
    > 6 | _addDeviceToGroup,
    | ^
    7 | } = NativeModules._BleAssociator
    8 | const {
    9 | _queryName,

    at Object._addDeviceToGroup (app/utils/mesh.js:6:3)
    at Object.<anonymous> (app/actions/hierarchy.js:26:1)
    at Object.<anonymous> (app/actions/organizations.js:14:1)


    It seems as though the issue arose when we implemented custom Native Modules written by our backend team (again, before my joining the team).



    After some research, I decided to proceed under the assumption that this has to do with Jest's inability to parse the Objective-C in the Engine that's feeding in the Native Modules and not some issue with our stack (happy to consider that possibility, though).



    I've reviewed the Jest documentation, combing specifically through a couple relevant documents (Mock Functions, Using Jest with ES Module Imports, Testing Native Modules with Jest Mock, React Native Modules Guide)



    My issue appears to be identical to this issue; however, the fix is not working for me. Even when mocking the NativeModules, I get the same error.



    I've become familiar with the notion that Jest mocks are hoisted above the import statements, but it's not clear to me why the mocks are in the describe block in the issue I linked above (other than maybe to reset the mock function for each new test in case so as to not confound the .mock property's return data... I digress).



    To me, it seems the error is occurring during the imports, before any of the code is executed. To test this, I've gone back and forth, commenting out everything but the import statements and the mocks. Doing this, I still get the same error. This is also the case when I use a beforeEach() mocha statement, as in the solution to the issue linked above.



    The only thing that fixes this error commenting out the imports altogether.



    I have not tried error handling (try/catch), as I'm not certain how I could still successfully import the component I'm testing if the catch block is executed.



    Sorry for all that background. I have spent a couple workdays on this, so I want to make certain all my bases are covered.



    Here's an example test:



    /__tests__/app/components/Onboarding/Splash/Splash.test.js






    import {
    NativeModules,
    } from 'react-native';

    import { Splash } from '../../../../../app/components/Onboarding/Splash/Splash.js';
    // import login from '../../../../../app/actions/login';

    // NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
    // login = jest.fn;

    export default function({React, shallow}) {

    const props = {
    // some test props
    };

    function make({navigation, getUserInfo, verifyUser, login} = props) {
    return shallow(
    // renders the component with props
    );
    }

    describe('<Splash />', () => {
    // I added this part (didn't help)
    beforeEach(() => {
    NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
    login = jest.fn;
    });
    // end part I added

    // stuff (all the tests are in here)

    });

    }





    The NativeModules and login imports, the commented out lines, and the beforeEach() block are things I've tried intermittently to no avail.



    When trying to trace this error, I found that commenting out import statement in the original Splash.js that run scripts (as ES6 import runs the script it references) that try to import NativeModules fixes the error I see. As you might have gleaned from the stack trace, these go many levels deep.



    PHEW. If you've read this far, I really appreciate the help.



    Sorry to have such a long and complicated question. As you can see, we have a large and convoluted stack. It's possible the fix from the issue above isn't working because of how many chained imports happen before getting to the error.



    I'd love it if it's a tiny fix that I'm missing or if there was some sort of "shallow"-ish import that I'm not aware of.



    Thanks a bajillion for your help. Any input is welcome.










    share|improve this question



























      0












      0








      0








      I've recently been brought on to a team as Test Engineer and I'm trying to get Jest unit tests up and running on our React Native app. My predecessor has already authored dozens of unit tests, most of which are not running successfully.



      I'm getting the following error when running npm test



       FAIL  __tests__/index.test.js
      ● Test suite failed to run

      TypeError: Cannot read property '_addDeviceToGroup' of undefined

      4 | } from 'react-native';
      5 | const {
      > 6 | _addDeviceToGroup,
      | ^
      7 | } = NativeModules._BleAssociator
      8 | const {
      9 | _queryName,

      at Object._addDeviceToGroup (app/utils/mesh.js:6:3)
      at Object.<anonymous> (app/actions/hierarchy.js:26:1)
      at Object.<anonymous> (app/actions/organizations.js:14:1)


      It seems as though the issue arose when we implemented custom Native Modules written by our backend team (again, before my joining the team).



      After some research, I decided to proceed under the assumption that this has to do with Jest's inability to parse the Objective-C in the Engine that's feeding in the Native Modules and not some issue with our stack (happy to consider that possibility, though).



      I've reviewed the Jest documentation, combing specifically through a couple relevant documents (Mock Functions, Using Jest with ES Module Imports, Testing Native Modules with Jest Mock, React Native Modules Guide)



      My issue appears to be identical to this issue; however, the fix is not working for me. Even when mocking the NativeModules, I get the same error.



      I've become familiar with the notion that Jest mocks are hoisted above the import statements, but it's not clear to me why the mocks are in the describe block in the issue I linked above (other than maybe to reset the mock function for each new test in case so as to not confound the .mock property's return data... I digress).



      To me, it seems the error is occurring during the imports, before any of the code is executed. To test this, I've gone back and forth, commenting out everything but the import statements and the mocks. Doing this, I still get the same error. This is also the case when I use a beforeEach() mocha statement, as in the solution to the issue linked above.



      The only thing that fixes this error commenting out the imports altogether.



      I have not tried error handling (try/catch), as I'm not certain how I could still successfully import the component I'm testing if the catch block is executed.



      Sorry for all that background. I have spent a couple workdays on this, so I want to make certain all my bases are covered.



      Here's an example test:



      /__tests__/app/components/Onboarding/Splash/Splash.test.js






      import {
      NativeModules,
      } from 'react-native';

      import { Splash } from '../../../../../app/components/Onboarding/Splash/Splash.js';
      // import login from '../../../../../app/actions/login';

      // NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      // login = jest.fn;

      export default function({React, shallow}) {

      const props = {
      // some test props
      };

      function make({navigation, getUserInfo, verifyUser, login} = props) {
      return shallow(
      // renders the component with props
      );
      }

      describe('<Splash />', () => {
      // I added this part (didn't help)
      beforeEach(() => {
      NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      login = jest.fn;
      });
      // end part I added

      // stuff (all the tests are in here)

      });

      }





      The NativeModules and login imports, the commented out lines, and the beforeEach() block are things I've tried intermittently to no avail.



      When trying to trace this error, I found that commenting out import statement in the original Splash.js that run scripts (as ES6 import runs the script it references) that try to import NativeModules fixes the error I see. As you might have gleaned from the stack trace, these go many levels deep.



      PHEW. If you've read this far, I really appreciate the help.



      Sorry to have such a long and complicated question. As you can see, we have a large and convoluted stack. It's possible the fix from the issue above isn't working because of how many chained imports happen before getting to the error.



      I'd love it if it's a tiny fix that I'm missing or if there was some sort of "shallow"-ish import that I'm not aware of.



      Thanks a bajillion for your help. Any input is welcome.










      share|improve this question
















      I've recently been brought on to a team as Test Engineer and I'm trying to get Jest unit tests up and running on our React Native app. My predecessor has already authored dozens of unit tests, most of which are not running successfully.



      I'm getting the following error when running npm test



       FAIL  __tests__/index.test.js
      ● Test suite failed to run

      TypeError: Cannot read property '_addDeviceToGroup' of undefined

      4 | } from 'react-native';
      5 | const {
      > 6 | _addDeviceToGroup,
      | ^
      7 | } = NativeModules._BleAssociator
      8 | const {
      9 | _queryName,

      at Object._addDeviceToGroup (app/utils/mesh.js:6:3)
      at Object.<anonymous> (app/actions/hierarchy.js:26:1)
      at Object.<anonymous> (app/actions/organizations.js:14:1)


      It seems as though the issue arose when we implemented custom Native Modules written by our backend team (again, before my joining the team).



      After some research, I decided to proceed under the assumption that this has to do with Jest's inability to parse the Objective-C in the Engine that's feeding in the Native Modules and not some issue with our stack (happy to consider that possibility, though).



      I've reviewed the Jest documentation, combing specifically through a couple relevant documents (Mock Functions, Using Jest with ES Module Imports, Testing Native Modules with Jest Mock, React Native Modules Guide)



      My issue appears to be identical to this issue; however, the fix is not working for me. Even when mocking the NativeModules, I get the same error.



      I've become familiar with the notion that Jest mocks are hoisted above the import statements, but it's not clear to me why the mocks are in the describe block in the issue I linked above (other than maybe to reset the mock function for each new test in case so as to not confound the .mock property's return data... I digress).



      To me, it seems the error is occurring during the imports, before any of the code is executed. To test this, I've gone back and forth, commenting out everything but the import statements and the mocks. Doing this, I still get the same error. This is also the case when I use a beforeEach() mocha statement, as in the solution to the issue linked above.



      The only thing that fixes this error commenting out the imports altogether.



      I have not tried error handling (try/catch), as I'm not certain how I could still successfully import the component I'm testing if the catch block is executed.



      Sorry for all that background. I have spent a couple workdays on this, so I want to make certain all my bases are covered.



      Here's an example test:



      /__tests__/app/components/Onboarding/Splash/Splash.test.js






      import {
      NativeModules,
      } from 'react-native';

      import { Splash } from '../../../../../app/components/Onboarding/Splash/Splash.js';
      // import login from '../../../../../app/actions/login';

      // NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      // login = jest.fn;

      export default function({React, shallow}) {

      const props = {
      // some test props
      };

      function make({navigation, getUserInfo, verifyUser, login} = props) {
      return shallow(
      // renders the component with props
      );
      }

      describe('<Splash />', () => {
      // I added this part (didn't help)
      beforeEach(() => {
      NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      login = jest.fn;
      });
      // end part I added

      // stuff (all the tests are in here)

      });

      }





      The NativeModules and login imports, the commented out lines, and the beforeEach() block are things I've tried intermittently to no avail.



      When trying to trace this error, I found that commenting out import statement in the original Splash.js that run scripts (as ES6 import runs the script it references) that try to import NativeModules fixes the error I see. As you might have gleaned from the stack trace, these go many levels deep.



      PHEW. If you've read this far, I really appreciate the help.



      Sorry to have such a long and complicated question. As you can see, we have a large and convoluted stack. It's possible the fix from the issue above isn't working because of how many chained imports happen before getting to the error.



      I'd love it if it's a tiny fix that I'm missing or if there was some sort of "shallow"-ish import that I'm not aware of.



      Thanks a bajillion for your help. Any input is welcome.






      import {
      NativeModules,
      } from 'react-native';

      import { Splash } from '../../../../../app/components/Onboarding/Splash/Splash.js';
      // import login from '../../../../../app/actions/login';

      // NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      // login = jest.fn;

      export default function({React, shallow}) {

      const props = {
      // some test props
      };

      function make({navigation, getUserInfo, verifyUser, login} = props) {
      return shallow(
      // renders the component with props
      );
      }

      describe('<Splash />', () => {
      // I added this part (didn't help)
      beforeEach(() => {
      NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      login = jest.fn;
      });
      // end part I added

      // stuff (all the tests are in here)

      });

      }





      import {
      NativeModules,
      } from 'react-native';

      import { Splash } from '../../../../../app/components/Onboarding/Splash/Splash.js';
      // import login from '../../../../../app/actions/login';

      // NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      // login = jest.fn;

      export default function({React, shallow}) {

      const props = {
      // some test props
      };

      function make({navigation, getUserInfo, verifyUser, login} = props) {
      return shallow(
      // renders the component with props
      );
      }

      describe('<Splash />', () => {
      // I added this part (didn't help)
      beforeEach(() => {
      NativeModules._BleAssociator._addDeviceToGroup = jest.fn();
      login = jest.fn;
      });
      // end part I added

      // stuff (all the tests are in here)

      });

      }






      javascript ios react-native jestjs babel-jest






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 29 '18 at 23:57







      jebrii

















      asked Nov 28 '18 at 0:35









      jebriijebrii

      43




      43
























          1 Answer
          1






          active

          oldest

          votes


















          0














          I found the solution to this. I had been worried that perhaps the mocks weren't being tracked through all the import statement. What was really happening was I was formatting the mocks wrong.



          I did not see this in the standard Jest documentation, but instead found it here.



          Adding this to my *.test.js files worked:



          import { NativeModules } from 'react-native';
          jest.mock('NativeModules', () => {
          return {
          _BleAssociator: {
          _addDeviceToGroup: jest.fn()
          },
          // ... and so on for all the other methods expected in NodeModules
          };
          });


          Just for posterity's sake, I think this would be best kept in its own script and imported into the tests... I haven't tried this yet.






          share|improve this answer


























          • Just a note for later readers: The best implementation for this was running the above code in its own script using the setupFiles config feature (jestjs.io/docs/en/configuration#setupfiles-array) in Jest

            – jebrii
            Nov 29 '18 at 23:59













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53510385%2fjest-error-when-trying-to-import-native-modules-unable-to-prevent-with-mock%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          I found the solution to this. I had been worried that perhaps the mocks weren't being tracked through all the import statement. What was really happening was I was formatting the mocks wrong.



          I did not see this in the standard Jest documentation, but instead found it here.



          Adding this to my *.test.js files worked:



          import { NativeModules } from 'react-native';
          jest.mock('NativeModules', () => {
          return {
          _BleAssociator: {
          _addDeviceToGroup: jest.fn()
          },
          // ... and so on for all the other methods expected in NodeModules
          };
          });


          Just for posterity's sake, I think this would be best kept in its own script and imported into the tests... I haven't tried this yet.






          share|improve this answer


























          • Just a note for later readers: The best implementation for this was running the above code in its own script using the setupFiles config feature (jestjs.io/docs/en/configuration#setupfiles-array) in Jest

            – jebrii
            Nov 29 '18 at 23:59


















          0














          I found the solution to this. I had been worried that perhaps the mocks weren't being tracked through all the import statement. What was really happening was I was formatting the mocks wrong.



          I did not see this in the standard Jest documentation, but instead found it here.



          Adding this to my *.test.js files worked:



          import { NativeModules } from 'react-native';
          jest.mock('NativeModules', () => {
          return {
          _BleAssociator: {
          _addDeviceToGroup: jest.fn()
          },
          // ... and so on for all the other methods expected in NodeModules
          };
          });


          Just for posterity's sake, I think this would be best kept in its own script and imported into the tests... I haven't tried this yet.






          share|improve this answer


























          • Just a note for later readers: The best implementation for this was running the above code in its own script using the setupFiles config feature (jestjs.io/docs/en/configuration#setupfiles-array) in Jest

            – jebrii
            Nov 29 '18 at 23:59
















          0












          0








          0







          I found the solution to this. I had been worried that perhaps the mocks weren't being tracked through all the import statement. What was really happening was I was formatting the mocks wrong.



          I did not see this in the standard Jest documentation, but instead found it here.



          Adding this to my *.test.js files worked:



          import { NativeModules } from 'react-native';
          jest.mock('NativeModules', () => {
          return {
          _BleAssociator: {
          _addDeviceToGroup: jest.fn()
          },
          // ... and so on for all the other methods expected in NodeModules
          };
          });


          Just for posterity's sake, I think this would be best kept in its own script and imported into the tests... I haven't tried this yet.






          share|improve this answer















          I found the solution to this. I had been worried that perhaps the mocks weren't being tracked through all the import statement. What was really happening was I was formatting the mocks wrong.



          I did not see this in the standard Jest documentation, but instead found it here.



          Adding this to my *.test.js files worked:



          import { NativeModules } from 'react-native';
          jest.mock('NativeModules', () => {
          return {
          _BleAssociator: {
          _addDeviceToGroup: jest.fn()
          },
          // ... and so on for all the other methods expected in NodeModules
          };
          });


          Just for posterity's sake, I think this would be best kept in its own script and imported into the tests... I haven't tried this yet.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 28 '18 at 2:12

























          answered Nov 28 '18 at 1:30









          jebriijebrii

          43




          43













          • Just a note for later readers: The best implementation for this was running the above code in its own script using the setupFiles config feature (jestjs.io/docs/en/configuration#setupfiles-array) in Jest

            – jebrii
            Nov 29 '18 at 23:59





















          • Just a note for later readers: The best implementation for this was running the above code in its own script using the setupFiles config feature (jestjs.io/docs/en/configuration#setupfiles-array) in Jest

            – jebrii
            Nov 29 '18 at 23:59



















          Just a note for later readers: The best implementation for this was running the above code in its own script using the setupFiles config feature (jestjs.io/docs/en/configuration#setupfiles-array) in Jest

          – jebrii
          Nov 29 '18 at 23:59







          Just a note for later readers: The best implementation for this was running the above code in its own script using the setupFiles config feature (jestjs.io/docs/en/configuration#setupfiles-array) in Jest

          – jebrii
          Nov 29 '18 at 23:59






















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53510385%2fjest-error-when-trying-to-import-native-modules-unable-to-prevent-with-mock%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

          Calculate evaluation metrics using cross_val_predict sklearn

          Insert data from modal to MySQL (multiple modal on website)