"react": "^15.4.2",
"react-native": "^0.41.2",
"react-native-fcm": "^6.1.0",
When I run npm test, the following error comes up. I have no idea how to fix it because the project runs fine on both simulator and real device. The error only shows up during tests.
FAIL __tests__/index.ios.js
โ renders correctly
TypeError: Cannot read property 'requestPermissions' of undefined
at Object.<anonymous>.FCM.requestPermissions (node_modules/react-native-fcm/index.js:39:22)
at App.componentDidMount (index.ios.js:19:26)
at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:265:25
at measureLifeCyclePerf (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:75:12)
at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:264:11
at CallbackQueue.notifyAll (node_modules/react-test-renderer/lib/CallbackQueue.js:76:22)
at ReactTestReconcileTransaction.close (node_modules/react-test-renderer/lib/ReactTestReconcileTransaction.js:36:26)
at ReactTestReconcileTransaction.closeAll (node_modules/react-test-renderer/lib/Transaction.js:206:25)
at ReactTestReconcileTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:153:16)
at batchedMountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:69:27)
Here is my test file
import 'react-native';
import React from 'react';
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
import Index from '../index.ios';
it('renders correctly', () => {
renderer.create(
<Index />,
);
});
Here is my app delegate file
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import "RNFIRMessaging.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"JDIFrontend"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[FIRApp configure];
[[UNUserNotificationCenter currentNotificationCenter] setDelegate:self];
return YES;
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
[RNFIRMessaging willPresentNotification:notification withCompletionHandler:completionHandler];
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
[RNFIRMessaging didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
}
//You can skip this method if you don't want to use local notification
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[RNFIRMessaging didReceiveLocalNotification:notification];
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[RNFIRMessaging didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}
@end
I too am getting the same error while running npm run test
Versions:
"react": "15.4.2",
"react-native": "^0.42.0-rc.3",
"react-native-fcm": "^6.0.3",
App runs fine on a real device, did not test on emulator due to testing notifications.
Was able to find a decent solution: http://stackoverflow.com/a/42142331
Thanks for sharing! I ended up using the following mock function. You may need to mock more functions from react-native-fcm depending on which ones you used.
jest.mock('react-native-fcm', () =>({
on: jest.fn(),
requestPermissions: jest.fn(),
getFCMToken: jest.fn(()=> new Promise((accept, resolve) => accept('FakeToken'))),
FCMEvent: {
Notification: 'fakeNotification',
},
}));
@fever324
I had something very similar but kept getting an error that it couldn't find Notification. In the end, I opted for that solution found on SO.
Glad we were both able to figure out a working solution. I'm pretty new to React Native, so I don't exactly know which style is preferred over the other for Testing.
Thanks
looks like issue is solved
@fever324 I have the same problem. In which file did you place your code for the mock function?
Ok this got me out of trouble. The above example didn't work. This is literally my first effort with Jest and it almost certainly not best practice, but I can now run my test.
Add a react-native-fcm.js file, in a__mocks__directory next to thenode_modules` directory in your app root.
So
<app>
- node_modules
- __mocks__
- react-native-fcm.js
inside that file put the following code:
const fcm = jest.genMockFromModule('react-native-fcm');
fcm.default.getFCMToken =()=>new Promise((resolve, reject)=>{resolve()});
module.exports = fcm;
It seems you need to do a module.exports for it to work, and thats why the code in the previous comment wouldn't work.
Most helpful comment
Thanks for sharing! I ended up using the following mock function. You may need to mock more functions from
react-native-fcmdepending on which ones you used.