React-native-animatable: Unable to run tests

Created on 7 Feb 2017  Â·  21Comments  Â·  Source: oblador/react-native-animatable

I'm unable to test components having Animatable.View, I'm seeing the following error:

TypeError: UIManager.updateView is not a function

      at Component.setNativeProps (node_modules/react-native/Libraries/Renderer/src/renderers/native/NativeMethodsMixin.js:157:11)
      at AnimatedProps.callback [as _callback] (node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js:1757:20)
      at AnimatedProps.update (node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js:1625:6)
      at node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js:228:69
      at Set.forEach (native)
      at _flush (node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js:228:16)
      at AnimatedValue._updateValue (node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js:907:1)
      at AnimatedValue.setValue (node_modules/react-native/Libraries/Animated/src/AnimatedImplementation.js:738:6)
      at AnimatableComponent.startAnimation (node_modules/react-native-animatable/createAnimatableComponent.js:312:16)
      at startAnimation (node_modules/react-native-animatable/createAnimatableComponent.js:242:8)

Most helpful comment

This mock works for me

import React from 'react'
import { Image, Text } from 'react-native'

const createAnimatableComponent = Component => (
  class AnimatableComponent extends React.Component {
    render() {
      return <Component/>
    }
  }
)

const initializeRegistryWithDefinitions = jest.fn()

export {
  createAnimatableComponent,
  initializeRegistryWithDefinitions,
  Image,
  Text,
}

All 21 comments

Don't know about your test setup, but you probably just need to mock it.

@oblador This is my test setup -> https://github.com/arjunkomath/mjuzik
I'll try with mock

@oblador Even after using mock is not working. :(

import 'react-native';
import React from 'react';
import Mixtape from '../app/components/mixtape';
require('react-native-mock/mock');

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

var props = {
    navigation: {},
    details: {
        title: '',
        artwork_url: ''
    }
}

it('renders correctly', () => {
    const tree = renderer.create(
        <Mixtape {...props} />
    );
});

I tried with enzyme also. Its still not working:

> [email protected] test /Users/arjun/Documents/react_projects/mjuzik
> mocha --require react-native-mock/mock.js --compilers js:babel-core/register --recursive __tests__/*.js

/Users/arjun/Documents/react_projects/mjuzik/node_modules/react-native-animatable/index.js:1
(function (exports, require, module, __filename, __dirname) { import {
                                                              ^^^^^^
SyntaxError: Unexpected token import
    at Object.exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:513:28)
    at Module._extensions..js (module.js:550:10)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/arjun/Documents/react_projects/mjuzik/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/arjun/Documents/react_projects/mjuzik/app/components/mixtape.js:13:1)
    at Module._compile (module.js:541:32)
    at loader (/Users/arjun/Documents/react_projects/mjuzik/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/arjun/Documents/react_projects/mjuzik/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/arjun/Documents/react_projects/mjuzik/app/components/collection.js:13:1)
    at Module._compile (module.js:541:32)
    at loader (/Users/arjun/Documents/react_projects/mjuzik/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/arjun/Documents/react_projects/mjuzik/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/arjun/Documents/react_projects/mjuzik/__tests__/collection.js:5:1)
    at Module._compile (module.js:541:32)
    at loader (/Users/arjun/Documents/react_projects/mjuzik/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/arjun/Documents/react_projects/mjuzik/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at /Users/arjun/Documents/react_projects/mjuzik/node_modules/mocha/lib/mocha.js:222:27
    at Array.forEach (native)
    at Mocha.loadFiles (/Users/arjun/Documents/react_projects/mjuzik/node_modules/mocha/lib/mocha.js:219:14)
    at Mocha.run (/Users/arjun/Documents/react_projects/mjuzik/node_modules/mocha/lib/mocha.js:487:10)
    at Object.<anonymous> (/Users/arjun/Documents/react_projects/mjuzik/node_modules/mocha/bin/_mocha:459:18)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (node.js:348:7)
    at startup (node.js:140:9)
    at node.js:463:3

Hey, the problem is that you need to do babel transforms for this and most react-native modules as they are not precompiled. See the RN core jest config for inspiration.

i am new to react-native. could you please provide examples.

i am getting same error when i run npm test

screen shot 2017-04-26 at 12 38 20 pm

This is the closest issue we found when trying to write a test for a component that uses react-native-animatable's wrapped View component.

We were getting a TypeError: Cannot read property 'validAttributes' of undefined.

We got around this by mocking animatable and using RN's View in our tests instead.

Under __mocks__ if using jest, create a react-native-animatable.js file with this:

import { View } from 'react-native';

export {
  View
};

@dcarrot2 i have the same issue TypeError: Cannot read property 'validAttributes' of undefined but your solution didn't help :(

I solved this way, under __mocks__ if using jest, create a react-native-animatable.js file with this:
```import React, { Component } from 'react';
import {
View as CoreView,
Image as CoreImage,
Text as CoreText,
Animated
} from 'react-native';

export const createAnimatableComponent = (WrappedComponent) => {
const Animatable = Animated.createAnimatedComponent(WrappedComponent);
return class AnimatableComponent extends Component {
handleRef = ref => {
this.ref = ref;
};
transition() {}
stopAnimation() {}
stopAnimations() {}
// mock any other function you using

render() {

  return <Animatable ref={this.handleRef} {...this.props} />;
}

};
};
export const initializeRegistryWithDefinitions = () => {};
export const View = createAnimatableComponent(CoreView);
export const Text = createAnimatableComponent(CoreImage);
export const Image = createAnimatableComponent(CoreText);

This fix is not working for me. It still throws the error TypeError: Cannot read property 'validAttributes' of undefined for me. Any ideas on how to solve this? I got this error when using RN 0.45

@markhaasjes Perhaps you can mock animatable directly?

jest.mock('react-native-animatable', () => 'react-native-animatable');

Then I'll get the error

TypeError: (0 , _reactNativeAnimatable.initializeRegistryWithDefinitions) is not a function

Now try my suggestion per a few posts above, but mock initializedRegistryWithDefinitions.

import { View } from 'react-native';

const initializeRegistryWithDefinitions = jest.fn();
export {
  View,
  initializeRegistryWithDefinitions
};

This partly works for me. It solves the TypeError on initializeRegistryWithDefinitions but therefore transitionTo is not working anymore because it uses the View component of 'react-native'.

TypeError: _this.backdropRef.transitionTo is not a function

Can confirm, receiving same error as markhaasjes with:

└── [email protected]
└─┬ [email protected]
  └── [email protected]

I have encountered a similar issue. As pointed out in Jest docs for react-native. Most of the NPM packages depend on babel transformations and don't have their source code "pre-compiled" therefore errors are encountered.
That's where transformIgnorePatterns setting for Jest comes to play.

Adjusting settings to:

"jest": {
  "preset": "react-native",
  "transformIgnorePatterns": [
    "node_modules/(?!(jest-)?react-native|react-navigation|react-native-animatable)"
  ]
}

Solved any babel transformations related errors. However, a manual function mock is still required due to an error:
TypeError: Animatable.createAnimatableComponent is not a function

Creating a __mocks__ folder on the project's root directory (where node_modules folder resides) and a file react-native-animatable.js with the content of:

import React from 'react';

const createAnimatableComponent = Component => (
  class AnimatableComponent extends React.Component {
    render() {
      return <Component/>;
    }
  }
);

export {
  createAnimatableComponent
};

Solved all the issues for me.
However, one might need to expand the manual mock based on the functionality used. Personally, I have used only createAnimatableComponent hence minimal manual mock was enough.

can't run tests here, same issue

This mock works for me

import React from 'react'
import { Image, Text } from 'react-native'

const createAnimatableComponent = Component => (
  class AnimatableComponent extends React.Component {
    render() {
      return <Component/>
    }
  }
)

const initializeRegistryWithDefinitions = jest.fn()

export {
  createAnimatableComponent,
  initializeRegistryWithDefinitions,
  Image,
  Text,
}

@nschurmann's solution works for me but I have type warnings like this.

console.error node_modules/fbjs/lib/warning.js:33
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a 
class/function (for composite components) but got: undefined. You likely forgot to export your 
component from the file it's defined in, or you might have mixed up default and named imports.

anyone can solve this ?

@nschurmann's solution works for me but I have type warnings like this.

console.error node_modules/fbjs/lib/warning.js:33
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a 
class/function (for composite components) but got: undefined. You likely forgot to export your 
component from the file it's defined in, or you might have mixed up default and named imports.

anyone can solve this ?

jest.mock('react-native', () => ({
Animated: {
createAnimatedComponent: (Component) => Component,
},
}));

I had the same issue, with an error saying TypeError: _this.backdropRef.transitionTo is not a function

After browsing all the mocks in this issue, I found that a modified version of @scerelli suggestion should work:

import React, { Component } from 'react'
import {
  View as CoreView,
  Image as CoreImage,
  Text as CoreText,
  Animated,
} from 'react-native'

export const createAnimatableComponent = (WrappedComponent) => {
  const Animatable = Animated.createAnimatedComponent(WrappedComponent)

  return class AnimatableComponent extends Component {
    handleRef = (ref) => {
      this.ref = ref
    }
    transition() {}
    stopAnimation() {}
    stopAnimations() {}
    transitionTo() {} // <-- this fixes the error "TypeError: _this.backdropRef.transitionTo is not a function"
    animate() { // <-- this was required in my specific example
      return { then: () => {} }
    }
    // mock any other function you using

    render() {
      return <Animatable ref={this.handleRef} {...this.props} />
    }
  }
}
export const initializeRegistryWithDefinitions = () => {}
export const View = createAnimatableComponent(CoreView)
export const Text = createAnimatableComponent(CoreImage)
export const Image = createAnimatableComponent(CoreText)

(original: https://github.com/oblador/react-native-animatable/issues/97#issuecomment-307377808)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ggomaeng picture ggomaeng  Â·  5Comments

Aspirationtocode picture Aspirationtocode  Â·  7Comments

zr0n picture zr0n  Â·  6Comments

sundayhd picture sundayhd  Â·  5Comments

TrustDec picture TrustDec  Â·  3Comments