Saltar al contenido

Prueba Jest Animated.View para la aplicación React-Native

Hola usuario de nuestra página, encontramos la solución a lo que necesitas, deslízate y la obtendrás más abajo.

Solución:

Resolví este problema creando un código auxiliar animado para las pruebas.

Veo que está usando visible como una propiedad, por lo que un ejemplo de trabajo es:

Código de componentes

import React from 'react';                                                                                                                                                                            
import  Animated, Text, View, TouchableOpacity  from 'react-native';                                                                                                                                

// This class will control the visible prop                                                                                                                                                                                                  
class AnimatedOpacityController extends React.Component                                                                                                                                              

  constructor(props, ctx)                                                                                                                                                                            
    super(props, ctx);                                                                                                                                                                                
    this.state =                                                                                                                                                                                     
      showChild: false,                                                                                                                                                                               
    ;                                                                                                                                                                                                
                                                                                                                                                                                                     

  render()                                                                                                                                                                                           
    const  showChild  = this.state;                                                                                                                                                                 
    return (                                                                                                                                                                                          
                                                                                                                                                                                                
                                                                                                                                                    
         this.setState( showChild: !showChild )>                                                                                                                   
          showChild ? 'Hide' : 'Show'  greeting                                                                                                                                        
                                                                                                                                                                                   
                                                                                                                                                                                               
    );                                                                                                                                                                                                 
                                                                                                                                                                                                     

                                                                                                                                                                                                     

// This is your animated Component                                                                                                                                                                                                   
class AnimatedOpacity extends React.Component                                                                                                                                                        

  constructor(props, ctx)                                                                                                                                                                            
    super(props, ctx);                                                                                                                                                                                
    this.state =                                                                                                                                                                                     
      opacityValue: new Animated.Value(props.visible ? 1 : 0),                                                                                                                                                                                                                                                                                                               
    ;                                                                                                                                                                                                
  

  componentWillReceiveProps(nextProps)                                                                                                                                                               
    if (nextProps.visible !== this.props.visible)                                                                                                                                                    
      this._animate(nextProps.visible);                                                                                                                                                               
                                                                                                                                                                                                     
                                                                                                                                                                                                     

  _animate(visible)                                                                                                                                                                                  
    Animated.timing(this.state.opacityValue,                                                                                                                                                         
      toValue: visible ? 1 : 0,                                                                                                                                                                       
      duration: 350,                                                                                                                                                                                  
    ).start();                                                                                                                                                       
                                                                                                                                                                                                     

  render()                       
    return (                                                                                                                                                                                          
                                                                                                                                          
        Hello World                                                                                                                                                                      
                                                                                                                                                                                      
    );                                                                                                                                                                                                 

                                                                                                                                                                                                     

                                                                                                                                                                                                     


export  AnimatedOpacityController, AnimatedOpacity ;

Ahora pasando a las pruebas

import React from 'react';                                                                                                                                                                            
import renderer from 'react-test-renderer';                                                                                                                                                           
import  shallow  from 'enzyme';                                                                                                                                                                                                                                                                                                                                                                       

import  AnimatedOpacityController, AnimatedOpacity  from '../AnimatedOpacity';                                                                                                                    


jest.mock('Animated', () =>                                                                                                                                                                          
  const ActualAnimated = require.requireActual('Animated');                                                                                                                                           
  return                                                                                                                                                                                             
    ...ActualAnimated,                                                                                                                                                                                
    timing: (value, config) =>                                                                                                                                                                       
      return                                                                                                                                                                                         
        start: (callback) => 
          value.setValue(config.toValue);
          callback && callback()
        ,                                                                                                                                                  
      ;                                                                                                                                                                                              
    ,                                                                                                                                                                                                
  ;                                                                                                                                                                                                  
);                                                                                                                                                                                                                                                                                                                                                                                                     

it('renders visible', () =>                                                                                                                                                                          
  expect(                                                                                                                                                                                             
    renderer.create(                                                                                                                                                                                  
                                                                                                                                                                    
    ).toJSON()                                                                                                                                                                                        
  ).toMatchSnapshot();                                                                                                                                                                                
);                                                                                                                                                                                                   

it('renders invisible', () =>                                                                                                                                                                        
  expect(                                                                                                                                                                                             
    renderer.create(                                                                                                                                                                                  
                                                                                                                                                                   
    ).toJSON()                                                                                                                                                                                        
  ).toMatchSnapshot();                                                                                                                                                                                
);                                                                                                                                                                                                   

it('makes transition', () =>                                                                                                                                                                         
  const component = shallow();                                                                                                                                           
  expect(renderer.create(component.node).toJSON()).toMatchSnapshot();                                                                                                                                 
  component.find('TouchableOpacity').simulate('press');                                                                                                                                               
  expect(renderer.create(component.node).toJSON()).toMatchSnapshot();                                                                                                                                 
  component.find('TouchableOpacity').simulate('press');                                                                                                                                               
  expect(renderer.create(component.node).toJSON()).toMatchSnapshot();                                                                                                                                 
);                                                                                                                                                                                                   

Ahora las instantáneas generadas tendrán los valores de opacidad esperados. Si está usando mucho animado, puede mover su simulacro a js/config/jest y edite su package.json para usarlo en todas sus pruebas, luego cualquier cambio realizado en su código auxiliar estará disponible para todas las pruebas.

EDITADO:

La solución anterior se resuelve solo para ir de principio a fin. Una solución más granular es:

  1. No te burles animado
  2. En la configuración de broma hacer global.requestAnimationFrame = null
  3. Use mockdate para burlarse de la fecha
  4. Utilice jest.runTimersToTime para viajar en el tiempo

Una función de viaje en el tiempo sería

const timeTravel = (ms, step = 100) =>                                                                                                                                                                               

  const tickTravel = v =>                                                                                                                                                                                
    jest.runTimersToTime(v);                                                                                                                                                                              
    const now = Date.now();                                                                                                                                                                               
    MockDate.set(new Date(now + v));                                                                                                                                                                      
                                                                                                                                                                                                         

  let done = 0;                                                                                                                                                                                           
  while (ms - done > step)                                                                                                                                                                                
    tickTravel(step);                                                                                                                                                                                      
    done += step;                                                                                                                                                                                          
                                                                                                                                                                                                         
  tickTravel(ms - done);                                                                                                                                                                                  
;    

Es importante dividir los pasos en trozos pequeños debido al comportamiento interno animado.

EDIT de Aspirina fue útil para resolver este problema, pero no hizo el trabajo directamente. Para los que siguen, así es como resolví el problema de la simulación del progreso de la animación:

Estoy usando Jest: este es mi script setupTests.js que inicia el entorno de prueba

const MockDate = require('mockdate')
const frameTime = 10

global.requestAnimationFrame = (cb) => 
    // Default implementation of requestAnimationFrame calls setTimeout(cb, 0),
    // which will result in a cascade of timers - this generally pisses off test runners
    // like Jest who watch the number of timers created and assume an infinite recursion situation
    // if the number gets too large.
    //
    // Setting the timeout simulates a frame every 1/100th of a second
    setTimeout(cb, frameTime)


global.timeTravel = (time = frameTime) => 
    const tickTravel = () => 
        // The React Animations module looks at the elapsed time for each frame to calculate its
        // new position
        const now = Date.now()
        MockDate.set(new Date(now + frameTime))

        // Run the timers forward
        jest.advanceTimersByTime(frameTime)
    

    // Step through each of the frames
    const frames = time / frameTime
    let framesEllapsed
    for (framesEllapsed = 0; framesEllapsed < frames; framesEllapsed++) 
        tickTravel()
    

La idea aquí es que estamos reduciendo la velocidad de requestAnimationFrame para que sea exactamente 100 fps, y la función timeTravel le permite avanzar en incrementos de tiempo de un cuadro. Aquí hay un ejemplo de cómo usarlo (imagina que tengo una animación que tarda un segundo en completarse):

beforeEach(() => 
    // As part of constructing the Animation, it will grab the
    // current time. Mocking the date right away ensures everyone
    // is starting from the same time
    MockDate.set(0)

    // Need to fake the timers for timeTravel to work
    jest.useFakeTimers()
)

describe('half way through animation', () => 
  it('has a bottom of -175', () => 
    global.timeTravel(500)
    expect(style.bottom._value).toEqual(-175)
  )
)

describe('at end of animation', () => 
  it('has a bottom of 0', () => 
    global.timeTravel(1000)
    expect(style.bottom._value).toEqual(0)
  )
)

Aquí tienes las comentarios y calificaciones

Nos encantaría que puedieras comunicar esta noticia si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *