简体   繁体   English

开玩笑的嘲笑:如何模拟与react-native-randombytes的随机输出

[英]jest mock: how to mock random output with react-native-randombytes

I'm trying to write a jest unit test by replacing react-native-randombytes as it uses some NativeModules . 我正在尝试通过替换react-native-randombytes来编写一个react-native-randombytes单元测试,因为它使用了某些NativeModules

My error message: 我的错误讯息:

Test suite failed to run

TypeError: Cannot read property 'seed' of undefined

> 1 | const RandomBytes = jest.genMockFromModule('react-native-randombytes');
    |                          ^
  2 | 
  3 | const randomBytes = (l) => {
  4 |   let uint8 = new Uint8Array(l);

  at seed (node_modules/react-native-randombytes/index.js:15:21)
  at Object.init (node_modules/react-native-randombytes/index.js:57:1)
  at Object.genMockFromModule (__mocks__/react-native-randombytes.js:1:26)

I place a file react-native-randombytes inside __mocks__ folder beside node_modules 我在__mocks__旁边的node_modules文件夹中放置了一个react-native-randombytes __mocks__文件

const RandomBytes = jest.genMockFromModule('react-native-randombytes');

const randomBytes = (l) => {
  let uint8 = new Uint8Array(l);
  uint8 = uint8.map(() => Math.floor(Math.random() * 90)+10);
  return uint8;
};

const seed = randomBytes(4096);

RandomBytes.randomBytes = randomBytes;
RandomBytes.seed = seed;

export default RandomBytes;

I opened up the library I would like to mock and I found that instead of a class, it has the following section of code get executed at the end of it's index.js file. 我打开了我想模拟的库,发现它不是类,而是在index.js文件的末尾执行了以下部分代码。 link 链接

function init () {
  if (RNRandomBytes.seed) {
    let seedBuffer = toBuffer(RNRandomBytes.seed)
    addEntropy(seedBuffer)
  } else {
    seedSJCL()
  }
}

It seems that using jest.genMockFromModule will trigger the init function so the whole mocking failed. 似乎使用jest.genMockFromModule将触发init函数,因此整个模拟失败。 What are the considerations that I should have to choose which ways of mocking methods to use? 选择哪种模拟方法应该考虑哪些因素? In the documentation, it lists out various methods, but when to do which methods is not clearly recommended. 在文档中,它列出了各种方法,但是何时执行哪种方法并不明确建议。

Should I use jest.fn()? 我应该使用jest.fn()吗?

Please advice. 请指教。

UPDATE 1: 更新1:

I tried the following out in test file 我在测试文件中尝试了以下内容

jest.mock('react-native-randombytes');
const randomBytes = jest.fn().mockImplementation((l) => {
    let uint8 = new Uint8Array(l);
    uint8 = uint8.map(() => Math.floor(Math.random() * 90)+10);
    return uint8;
  });

result: it doesn't work. 结果:它不起作用。 It had same error. 它有同样的错误。

UPDATE 2: change my file inside mock as followed 更新2:如下更改我的文件在模拟

const R = jest.genMockFromModule('react-native-randombytes');

R.randomBytes = (l) => {
  let uint8 = new Uint8Array(l);
  uint8 = uint8.map(() => Math.floor(Math.random() * 90)+10);
  return uint8;
};

R.init = () => {};

export default R;

result: same error message. 结果:相同的错误消息。 It still goes to original react-native-randombytes. 它仍然使用原始的react-native-randombytes。

UPDATE 3: just like update 1 but with some twist inspired by this post 更新3:就像更新1但也有一些扭曲受此启发

jest.genMockFromModule('react-native-randombytes');
// eslint-disable-next-line import/first
import randomBytes from 'react-native-randombytes';

randomBytes.mockImplementation((l) => {
    let uint8 = new Uint8Array(l);
    uint8 = uint8.map(() => Math.floor(Math.random() * 90)+10);
    return uint8;
  });

result: same error message. 结果:相同的错误消息。

Please refer to my suggestions first if you are a jest newbie. 如果您是个新手,请先参考我的建议

There are many node_modules modules that depend on react-native-randombytes. 有许多node_modules模块依赖于react-native-randombytes。 You will go crazy running after each of them. 您会疯狂地追逐他们每个人。 Instead, you should find an upper level module and mock it and if it is only one function, just function mock. 相反,您应该找到一个上层模块并对其进行模拟,如果它只是一个函数,则只是函数模拟。 Example as shown below. 示例如下所示。

And I would suggest using a manual mock since these modules located at node_modules 我建议使用手动模拟,因为这些模块位于node_modules

Example 1: 范例1:

jest.mock('react-native-securerandom', (size) => {
  return {
    generateSecureRandom: jest.fn(() => {
      let uint8 = new Uint8Array(size);
      uint8 = uint8.map(() => Math.floor(Math.random() * 90)+10);
      return uint8;
    }),
  };
});

Example 2: 范例2:

'use strict';

const bip39 = jest.mock('react-native-bip39'); // genMockFromModule causes problem

bip39.generateMnemonic = jest.fn((l) => [
  'furth',
  'edessa',
  'injustices',
  'frankston',
  'serjeant',
  'khazar',
  'sihanouk',
  'longchamp',
  'stags',
  'pogroms',
  'coups',
  'upperparts',
  'endpoints',
  'infringed',
  'nuanced',
  'summing',
  'humorist',
  'pacification',
  'ciaran',
  'jamaat',
  'anteriorly',
  'roddick',
  'springboks',
  'faceted'
  ].slice(0, l));

bip39.validateMnemonic = jest.fn((_) => true);

bip39.mnemonicToSeed = jest.fn((_) => 'I am a mnemonic seed');

export default bip39;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM