react-native-fetch-blob icon indicating copy to clipboard operation
react-native-fetch-blob copied to clipboard

How to test code that depends on RNFetchBlob

Open neiker opened this issue 8 years ago • 24 comments

If I want to test a module and that module includes RNFetchBlob, I get this: react-native-fetch-blob/index.js:6 import { ^^^^^^ SyntaxError: Unexpected token import

That's because babel-core/register don't transpire code within node_modules by default. It I change the config to do it, as it's mentioned here, it crash in this line because NativeModules.RNFetchBlob it's undefined. I get stuck there so I change my es6 include to this dirty piece of code:

let RNFetchBlob;
if (process.env.NODE_ENV !== 'test') {
  // eslint-disable-next-line global-require
  RNFetchBlob = require('react-native-fetch-blob').default;
}

Any ideas how to solve this?

This is my test script: NODE_ENV='test' mocha 'app/**/__tests__/*.js' --compilers js:babel-core/register --require mocha_setup.js

neiker avatar Dec 11 '16 22:12 neiker

I am using Facebook's Jest and I get the same error.

    TypeError: Cannot read property 'DocumentDir' of undefined
      
      at Object.<anonymous> (node_modules/react-native-fetch-blob/fs.js:25:24)
      at Object.<anonymous> (node_modules/react-native-fetch-blob/index.js:20:9)

I did try mocking the module, but then I use a constant Blob from RNFetchBlob.polyfill.Blob that then fails the test as it will be "undefined".

Thanks.

layik avatar Dec 13 '16 10:12 layik

I am also experiencing the same error; "TypeError: Cannot read property 'DocumentDir' of undefined"

ohtangza avatar Jan 22 '17 15:01 ohtangza

@neiker @layik @ohtangza have you guys been able to remedy this issue? I'm having the same issue.

cc: @wkh237

rahimrahman avatar Jan 31 '17 16:01 rahimrahman

@rahimrahman nop, I just include RNFB conditionally based on NODE_ENV

neiker avatar Jan 31 '17 16:01 neiker

You have to mock the library. Was using the react-native-img-cache library which had a dependency to react-native-fetch-blob, so my jest is mocking that module.

EX:

jest.mock('react-native-img-cache', () => {
  return {
    DocumentDir: () => {},
    ImageCache: {
      get: {
        clear: () => {}
      }
    }
  }
})

jnrepo avatar May 08 '17 07:05 jnrepo

Agreed with @jnrepo, the key is to mock the objects you are accessing in your code, code work for me

jest.mock('react-native-fetch-blob', () => {
  return {
    DocumentDir: () => {},
    polyfill: () => {},
  }
});

leyuan avatar Jun 13 '17 17:06 leyuan

I created a file inside the __mocks__ folder called react-native-fetch-blob.js and i mocked all the keys this way:

jest.mock('react-native-fetch-blob', () => {
  return {
    DocumentDir: () => {},
    fetch: () => {},
    base64: () => {},
    android: () => {},
    ios: () => {},
    config: () => {},
    session: () => {},
    fs: () => {},
    wrap: () => {},
    polyfill: () => {},
    JSONStream: () => {}
  };
});

but i still get an error related to the dir constants: TypeError: Cannot read property 'dirs' of undefined

any idea?

scerelli avatar Jul 10 '17 10:07 scerelli

@scerelli try this

  return {
    DocumentDir: () => {},
    fetch: () => {},
    base64: () => {},
    android: () => {},
    ios: () => {},
    config: () => {},
    session: () => {},
    fs: {
      dirs: {
        MainBundleDir: () => {},
        CacheDir: () => {},
        DocumentDir: () => {},
      },
    },
    wrap: () => {},
    polyfill: () => {},
    JSONStream: () => {}
  }
})```

SoundBlaster avatar Jul 18 '17 11:07 SoundBlaster

thx @SoundBlaster but this doesn't solve the error.

scerelli avatar Jul 18 '17 16:07 scerelli

+1,After reinstall, delete app,restart, also failed.

edit When I make another configuration in my Podfile. Now everything is ok.

aofeng2009 avatar Jul 27 '17 09:07 aofeng2009

@scerelli mines setup this way

in package.json:

"jest": {
    "preset": "react-native",
    "setupFiles": [
      "./test/setup.js"
    ],
    "coveragePathIgnorePatterns": [
      "/test/"
    ],
    "moduleFileExtensions": [
      "js",
      "json"
    ]
  }

in test/setup.js:

jest.mock('react-native-img-cache', () => {
  return {
    DocumentDir: () => {},
    ImageCache: {
      get: {
        clear: () => {}
      }
    }
  }
})

react-native-img-cache was the module using the react-native-fetch-blob. Perhaps its not react-native-fetch-blob, but another module thats using it?

jnrepo avatar Jul 27 '17 20:07 jnrepo

@jnrepo look this is the fetch-blob mocked log and this is the jest error:

https://cl.ly/3E3C242g1M1K

and the line raising this error is:

 const config = {
      overwrite : false,
      path: `${RNFetchBlob.fs.dirs.DocumentDir}/videos`,
      fileCache
    };

scerelli avatar Aug 22 '17 16:08 scerelli

I'm doing all the mocks correctly, AFAIK, but this is the error I get:

Test suite failed to run

ReferenceError: self is not defined
  
  at node_modules/react-native-fetch-blob/lib/oboe-browser.min.js:1:12597
  at Object.<anonymous> (node_modules/react-native-fetch-blob/lib/oboe-browser.min.js:1:12611)
  at Object.<anonymous> (node_modules/react-native-fetch-blob/json-stream.js:1:391)
  at Object.<anonymous> (node_modules/react-native-fetch-blob/index.js:28:17)

Seems to be something with the minified oboe code... any idea how to resolve that one?

jasongaare avatar Aug 31 '17 04:08 jasongaare

https://github.com/wkh237/react-native-fetch-blob/blob/master/lib/oboe-browser.js#L2701

It indeed is not defined, the line where it is used is the only line where it is mentioned. // cc @wkh237

Is it supposed to be this property? https://developer.mozilla.org/en/docs/Web/API/Window/self

lll000111 avatar Aug 31 '17 15:08 lll000111

Does it help if you add this line at the beginning of your program ?

global.self = {}

wkh237 avatar Aug 31 '17 15:08 wkh237

@jasongaare I think you need this:

https://github.com/johanneslumpe/react-native-browser-polyfill

It provides the global self property: https://developer.mozilla.org/en/docs/Web/API/Window/self

Okay, it consists of a single line of code, see https://github.com/johanneslumpe/react-native-browser-polyfill/blob/master/polyfills/globalself.js

For ref.: RN issue https://github.com/facebook/react-native/issues/1419

lll000111 avatar Aug 31 '17 15:08 lll000111

@wkh237 Actually, I think we need to include this, since it's RNFB code that uses self. It doesn't exist in RN, it seems.

lll000111 avatar Aug 31 '17 16:08 lll000111

@wkh237 @lll000111

Sorry just circling back to this... adding global.self = {} does allow my tests to run! I'm going to run with that solution for the timebeing

jasongaare avatar Sep 06 '17 03:09 jasongaare

As @scerelli I also wanted the mock to happen in a separate place so it can be used by all tests. Placing the following code in <project_root>/__mocks__/react-native-fetch-blob.js seems to work for me:

const existsMock = jest.fn();
existsMock.mockReturnValueOnce({then: jest.fn()});

export default {
    DocumentDir: () => {},
    ImageCache: {
        get: {
            clear: () => {},
        },
    },
    fs: {
        exists: existsMock,
        dirs: {
            MainBundleDir: () => {},
            CacheDir: () => {},
            DocumentDir: () => {},
        },
    },
};

It's a variation of @SoundBlaster solution, just in a global mock file. With that I don't need to import or implicitly mock anything in the test code.

maldimirov avatar Oct 31 '17 09:10 maldimirov

for me this object works as mock

jest.mock('react-native-fetch-blob', () => {
  return {
    fs: {
      dirs: {
        DocumentDir: ''
      },
      writeFile: () => Promise.resolve()
    }
  }
})

ThaJay avatar Dec 01 '17 16:12 ThaJay

Hi. If someone still get an error

/node_modules/redux-persist-filesystem-storage/index.js:5
import RNFetchBlob from 'react-native-fetch-blob'
^^^^^^    
SyntaxError: Unexpected token import

just add into "jest" section of package.json following option

"transformIgnorePatterns": [
  "node_modules/(?!react-native|react-navigation)/"
]

mikeevstropov avatar Dec 27 '17 08:12 mikeevstropov

@maldimirov thanks your solution, you save my life ! 💯

anhnguyenvan-agilityio avatar Sep 05 '18 14:09 anhnguyenvan-agilityio

The jest.mock should be added to documentation. Really useful

linnett avatar Oct 03 '18 15:10 linnett

@maldimirov You are awesome!

indapublic avatar Oct 05 '18 12:10 indapublic