2016-03-22 17 views
17

Kökteki her şeyi yüklemeden/oluşturmadan, bir kök bileşeninden içeriği miras alan bir bileşeni test etmeye çalışıyorum. Bağlamı nasıl yapacağımıza dair örnekler denedim ve aradım ama hiçbir şey bulamadım (en azından bu jest kullanmayan).React js - Bileşeni test ederken Bağlam nasıl yapılır?

İşte başarmaya çalıştığım şeyin basitleştirilmiş bir örneğidir.

Test için reactEl.context ile uğraşmamın basit bir yolu var mı?

/** 
* Root Element that sets up & shares context 
*/ 
class Root extends Component { 
    getChildContext() { 
    return { 
     language: { text: 'A String'} 
    }; 
    } 

    render() { 
    return (
     <div> 
     <ElWithContext /> 
     </div> 
    ); 
    } 
} 

Root.childContextTypes = { language: React.PropTypes.object }; 

/** 
* Child Element which uses context 
*/ 
class ElWithContext extends React.Component{ 
    render() { 
    const {language} = this.context; 
    return <p>{language.text}</p> 
    } 
} 

ElWithContext.contextTypes = { language: React.PropTypes.object } 



/** 
* Example test where context is unavailable. 
*/ 
let el = React.createElement(ElWithContext) 

element = TestUtils.renderIntoDocument(el); 
// ERROR: undefined is not an object (evaluating 'language.text') 

describe("ElWithContext",() => { 
    it('should contain textContent from context',() => { 
    const node = ReactDOM.findDOMNode(element); 
    expect(node.textContent).to.equal('A String'); 
    }); 
}) 
+0

bu npm modülü ?: https://www.npmjs.com/package/react-stub-context – JordanHendrix

+0

Teşekkür @Omarjmh bakınız, ben olsa nedeniyle jest kullanılan üstlendi şunu gördün mü örnek. Ama bence bu varsayım yanlış olabilir. – patnz

cevap

3

İçeriğiyle bir sarma bileşeni oluşturma çözümüyle gittim. Yaptığın aynı konuya girdi ve bunu yapmanın iki yolu öğrendim

/** 
* Helper function to wrap component with a component that has context 
*/ 
function wrapWithContext(context, contextTypes, children, React){ 

    const wrapperWithContext = React.createClass({ 
     childContextTypes: contextTypes, 
     getChildContext: function() { return context }, 
     render: function() { return React.createElement('div', null, children) } 
    }); 

    return React.createElement(wrapperWithContext); 
} 

/** 
* Usage 
*/ 

// in setup function of test framework 
const el = React.createElement(ElWithContext); 

const context = { language: { text: 'A String' } }; 
const contextTypes = { language: React.PropTypes.object }; 
const wrapper = wrapWithContext(context, contextTypes, [el], React); 
const ElWithContext = TestUtils.renderIntoDocument(wrapper); 

// do tests 
describe('ElWithContext',() => { 
    it('should contain textContent from context',() => { 
     const node = ReactDOM.findDOMNode(element); 
     expect(node.textContent).to.equal('A String'); 
    }); 
}) 
10

: bu büyük bir yaklaşımdır ama şu anda işime yarayıp emin değilim.

Birincisi, kendi yolunuza ait temel bir kopyacıdır: Bileşenimin etrafına bir sarıcı oluşturun ve onu dinamik bir bağlamla enjekte edin. Kaynak kodunu, ilgilenenler için aşağıya koydum, çünkü ES6 örneğinizin aksine. Ama sadece ES6 ve 'da nasıl yapıldığını göstermek için bunu kullanan herkese tavsiye etmiyorum (aslında kendim test etmedim).

src/testUtils/mockWithContext.js

import React, { Component } from 'react'; 
import wrapDisplayName from 'recompose/wrapDisplayName'; 
import hoistStatics from 'recompose/hoistStatics'; 

export const defaultContext = { 
    permissions: [ 

    ], 
    user: { 
    id: '1', 
    display_name: 'Default user', 
    email: '<your.email>[email protected]', // Trick with "+" for infinite aliases using gmail. 
    username: 'default_user', 
    created: '2016-08-01T15:50:13.246Z', 
    }, 
}; 

export const defaultContextType = { 
    permissions: React.PropTypes.array, 
    user: React.PropTypes.shape({ 
    id: React.PropTypes.string.isRequired, 
    display_name: React.PropTypes.string.isRequired, 
    email: React.PropTypes.string.isRequired, 
    username: React.PropTypes.string.isRequired, 
    created: React.PropTypes.string.isRequired, 
    }), 
}; 

/** 
* HOC for context 
*/ 
const withContext = ({ context = defaultContext, contextType = defaultContextType }) => (WrappedComponent) => { 
    class WithContext extends Component { 
    getChildContext() { 
     return context; 
    } 

    render() { 
     return <WrappedComponent {...this.props} />; 
    } 
    } 

    WithContext.displayName = wrapDisplayName(WrappedComponent, 'WithContext'); 
    WithContext.WrappedComponent = WrappedComponent; 
    WithContext.childContextTypes = contextType; 

    return WithContext; 
}; 

export default hoistStatics(withContext); 

Dediğim gibi ben yazdım ama bağlam enjekte yapmanın çok daha iyi bir yol bulduk çünkü test etmedi Bu alay için test yazmaya çalışırken. Kesinlikle bileşenleri test Tepki desteklemek için kurulmuştur Enzim kütüphane, kullanma

, test amaç için bileşeni işlemek shallow/mount/static yeteneği vardır. Ve bu yöntemlerin her biri ikinci bir argümana izin verir: bağlam.

SimpleComponent.js

const SimpleComponent = React.createClass({ 
    contextTypes: { 
    name: React.PropTypes.string, 
    }, 
    render() { 
    return <div>{this.context.name}</div>; 
    }, 
}); 

SimpleComponent.test.js

const context = { name: 'foo' }; 
const wrapper = mount(<SimpleComponent />, { context }); 
expect(wrapper.text()).to.equal('foo'); 
wrapper.setContext({ name: 'bar' }); 
expect(wrapper.text()).to.equal('bar'); 
wrapper.setContext({ name: 'baz' }); 
expect(wrapper.text()).to.equal('baz'); 

Oldukça düz ileri. Henüz kullanmadım ama ne yapmak istediğime benziyor. Sanırım kendi uygulamamı çöp kutusuna atmam gerekecek.

http://airbnb.io/enzyme/docs/api/ReactWrapper/setContext.html

İlgili konular