2016-06-13 4 views
21

.iç içe bileşenler test başka "bağlı bileşen" (yani <code>container</code>) monte edilen bir bileşeni <code>SampleComponent</code> sahip tepki ve Redux

Invariant Violation: Could not find "store" in either the context or props of "Connect(ContainerComponent)". Either wrap the root component in a , or explicitly pass "store" as a prop to "Connect(ContainerComponent)".

bu test etmenin en iyi yolu nedir: (Ben componentDidMount ihtiyacım beri) mount ing SampleComponent test etmek çalıştığımda, hata alıyorum?

cevap

4

ben aslında benim redux deposunda (ve Provider) getirmek ve aşağıdaki gibi bir yardımcı bileşeninde bunu sarılmış ne yaptı: Sonra

export const CustomProvider = ({ children }) => { 
    return (
    <Provider store={store}> 
     {children} 
    </Provider> 
); 
}; 

, buna karşı SampleComponent kontrol ediyorlar mount:

it('contains <ChildComponent/> Component',() => { 
    const wrapper = mount(
    <CustomProvider> 
     <SampleComponent {...defaultProps} /> 
    </CustomProvider> 
); 
    expect(wrapper.find(ChildComponent)).to.have.length(1); 
}); 
+0

Montajı kullandığınızı görüyorum, eğer '' mount'' ile '' shallo'' değiştirmeye çalışırsam bir hata alıyorum. bununla da mı karşılaştın? – Mehrdad

+2

Bu yanıt bazı durumlarda çalışırken, bileşeninizin yaşam döngüsünü sınamanız gerektiğinde çalışmaz. Örneğin, 'wrapper.setProps()' işlevini çağırmak 'SampleComponent' üzerinde' componentWillReceiveProps() 'öğesini başlatmaz. –

25

Enzimlerin bağlama isteğe bağlı parametreleri alır. Şimdi SampleComponent sen aşağı sağlanan bağlam geçecek

const store = { 
    subscribe:() => {}, 
    dispatch:() => {}, 
    getState:() => ({ ... whatever state you need to pass in ... }) 
} 
const options = { 
    context: { store }, 
    childContextTypes: { store: React.PropTypes.object.isRequired } 
} 

const _wrapper = mount(<SampleComponent {...defaultProps} />, options) 

: neye ihtiyacınız için gerekli olan iki Bir seçeneklerle SampleComponent şöyle itiraz monte ediyorum

options.context: (Object [optional]): Context to be passed into the component

options.childContextTypes: (Object [optional]): Merged contextTypes for all children of the wrapper vardır .

class SampleComponent extends React.Component{ 
... 
    render(){ 
     <div></div> 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(SampleComponent) 

Derse önce ihracat ekleyebilirsiniz:

export class SampleComponent extends React.Component{ 

ve hiçbir ile bu bileşeni ithal

Sen olmalıdır: Bu sorunu çözmek için isim verme kullanabilirsiniz

+2

Bu mükemmel! Kabul edilen cevap çoğu zaman işe yaramakla birlikte, olumsuzluk, api'yi tam kapasiteye kullanma yeteneğini kaybetmenizdir. Örneğin, bileşenin bir "Sağlayıcıda" sarılmasının kabul edilen yanıtının kullanılması, 'wrapper.state() 'api'nin kullanılmasına izin vermez. Bu çözüm size sarıcı için tam kapsamlı yöntemler sunar. – neurosnap

+0

Bu, kabul edilen yanıttan, yukarıda belirtilen nedenlerden dolayı (örn. Takılı paketleyiciniz aslında test etmeye çalıştığınız bileşen değildir) daha iyi bir yanıttır ve ayrıca gerçek mağazanız yerine sahte mağaza kullanabilirsiniz. Denklemin tamamı redux. – GTF

+2

bu isteğe bağlı argüman dokümanlar arasında değil, nasıl buldunuz? kodda? –

1

redux mağaza:

import { SampleComponent } from 'your-path/SampleComponent'; 

Bu çözümle, sınama dosyalarınıza depo almanız gerekmez.

1

Seçenek 1) Kapsayıcı bileşenini, testinizdeki React-Redux Sağlayıcı bileşeni ile sarabilirsiniz. Bu yaklaşımla, mağazaya başvuruda bulunuyorsunuz, bunu Tedarikçiye iletiyorsunuz ve içeriğinizi test altında oluşturuyorsunuz. Bu yaklaşımın avantajı, aslında test için özel bir mağaza oluşturabilirsiniz. Bu yaklaşım, bileşeninizin Redux ile ilgili kısımlarını test etmek istiyorsanız kullanışlıdır. Seçenek 2) Belki Redux ilgili parçalarını test umurumda değil. Bileşenin oluşturulmasını ve yerel durumla ilgili davranışlarını test etmekle ilgileniyorsanız, yalnızca bileşeninizin bağlantısız olan düz sürümü için adlandırılmış bir dışa aktarma ekleyebilirsiniz. Ve sadece "export" anahtar kelimesini sınıfınıza eklediğinizde açıklığa kavuşmak için, sınıfın artık küme parantezleri {} ile değil de 2 yolla alınabileceğini söylüyorsunuz. örnek:

export class MyComponent extends React.Component{ render(){ ... }} 

... 

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent) 

sonra test dosyası üzerinde:

import MyComponent from 'your-path/MyComponent'; // it needs a store because you use "default export" with connect 
import {MyComponent} from 'your-path/MyComponent'; // don't need store because you use "export" on top of your class. 

Umarım orada kimse yardımcı olur.

İlgili konular