2015-09-24 10 views
20

Attualmente sto sperimentando React + Relay + Graphql in questi giorni. Sfortunatamente, non riesco a trovare alcun modo facile e conveniente per testare il componente React avvolto da Relay Container.Testing strategy on Relay + React

In sostanza, vorrei raggiungere questi obiettivi insieme TDD,

  1. Render un contenitore e testare il suo contenuto,
  2. variabili Modificare e testare le sue modifiche al contenuto.

Rispetto a React + Flux, React + Relay è più simile a scatola nera, o, dichiarativo.

Riesco a vedere le persone che simulano Relay.createContainer per escludere il relè e testare semplicemente React Component. Lascia la parte di rilasci scoperta e non è possibile per unità questa parte testando. https://github.com/facebook/relay/issues/161

Inoltre, ho letto i casi di test di Relay ed è davvero noioso rendere un finto contenitore. https://github.com/facebook/relay/blob/master/src/tools/mocks/RelayTestUtils.js

Sarò davvero grato se è possibile condividere la soluzione.

Grazie!

+0

Penso che questa sia l'idea migliore: http://stackoverflow.com/questions/38327428/integration-testing- di relè-contenitori-con-jest-contro-un-lavoro-graphql-back –

risposta

12

Ho provato a testare i contenitori di inoltro come se fossero componenti in un'applicazione Flux. Nello specifico, voglio assicurarmi che visualizzino il contenuto corretto per un determinato stato e oggetti di scena e che chiamino metodi per cambiare i dati in luoghi appropriati; in Flux questa è una chiamata a un creatore di azioni, in Relay questa è una chiamata a Relay.Store.update o this.props.relay.setVariables.

Il mio primo tentativo è stato quello di creare un oggetto RelayTestUtil con un metodo renderContainerIntoDocument. L'ho basato pesantemente su https://github.com/facebook/relay/blob/master/src/tools/mocks/RelayTestUtils.js, https://github.com/facebook/relay/blob/master/src/legacy/store/mocks/GraphQLStoreQueryResolver.js e sui test del contenitore di rilancio. Questo ha usato il mocking molto minimale ed era ottimo per testare il rendering dei container ma era completamente inutile per testare le modifiche dei dati. Cercando di spiare le chiamate a Relay.Store.update e this.props.relay.setVariables, o di imitare le modifiche ai dati, è diventato più difficile di quanto valeva.

Ho optato per l'aggiunta di __mocks__\react-relay.js per il relè completamente simulato e utilizzando la versione più semplice di RelayTestUtils.renderContainerIntoDocument per iniettare le proprietà di inoltro in un contenitore. Non sono completamente soddisfatto di questa soluzione, ma sembra funzionare per ora.

__mocks__\react-relay.js:

var Relay = require.requireActual('react-relay'); 
var React = require('react'); 

module.exports = { 
    QL: Relay.QL, 
    Mutation: Relay.Mutation, 
    Route: Relay.Route, 
    Store: { 
    update: jest.genMockFn() 
    }, 
    createContainer: (component, containerSpec) => { 
    const fragments = containerSpec.fragments || {}; 

    // mock the static container methods 
    Object.assign(component, { getFragment: (fragmentName) => fragments[fragmentName] }); 

    return component; 
    } 
}; 

RelayTestUtils.js:

const React = require('react'); 
const ReactDOM = require('react-dom'); 


const RelayTestUtils = { 
    renderContainerIntoDocument(containerElement, relayOptions) { 
    relayOptions = relayOptions || {}; 

    const relaySpec = { 
     forceFetch: jest.genMockFn(), 
     getPendingTransactions: jest.genMockFn().mockImplementation(() => relayOptions.pendingTransactions), 
     hasOptimisticUpdate: jest.genMockFn().mockImplementation(() => relayOptions.hasOptimisticUpdate), 
     route: relayOptions.route || { name: 'MockRoute', path: '/mock' }, 
     setVariables: jest.genMockFn(), 
     variables: relayOptions.variables || {} 
    }; 

    return ReactDOM.render(
     React.cloneElement(containerElement, { relay: relaySpec }), 
     document.createElement('div') 
    ); 
    } 
}; 

export default RelayTestUtils; 

test simile a questa, dove fragmentData corrisponde alla forma della risposta GraphQL:

it('changes items',() => { 
    const myContainer = RelayTestUtils.renderContainerIntoDocument(
    <MyContainer { ...fragmentData }/>, 
    { variables: { itemId: 'asdf' } } 
); 
    myContainer.changeItem(); 
    expect(myContainer.props.relay.setVariables).toBeCalled(); 
}); 
+1

Non sarebbe anche possibile semplicemente 'schernire' il livello di rete? In modo simile al relay del pretender (https://github.com/pretenderjs/pretender) potrebbe effettivamente inviare la query, ma poi, invece di parlare con un server, torna semplicemente a dati falsi. – Markus

+1

@agrauch, potresti fornire un repo di esempio? –

Problemi correlati