2016-12-20 24 views
17

परीक्षण करते समय आप बच्चे के घटक का नकल कैसे करते हैं?चाकिंग बाल घटक - कोणीय 2

<section id="selected-container" class="container-fluid"> 
    <hr/> 
    <product-settings></product-settings> 
    <product-editor></product-editor> 
    <product-options></product-options> 
</section> 

और घटक घोषणा इस तरह दिखता है:

import { Component, Input }    from '@angular/core'; 

import { ProductSettingsComponent } from '../settings/product-settings.component';          
import { ProductEditorComponent } from '../editor/product-editor.component';          
import { ProductOptionsComponent } from '../options/product-options.component';           

@Component({ 
    selector: 'product-selected', 
    templateUrl: './product-selected.component.html', 
    styleUrls: ['./product-selected.component.scss'] 
}) 
export class ProductSelectedComponent {} 

इस घटक वास्तव में अन्य घटकों में रहते हैं और करने के लिए सिर्फ एक जगह है मैं एक माता पिता के घटक कहा जाता product-selected जिसका टेम्पलेट इस तरह दिखता है शायद कोई अन्य कार्य नहीं होगा।

Error: Template parse errors: 
    'product-editor' is not a known element: 
    1. If 'product-editor' is an Angular component, then verify that it is part of this module. 
    2. If 'product-editor' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. (" 
     <hr/> 
     <product-settings></product-settings> 
     [ERROR ->]<product-editor></product-editor> 

मैं बच्चे के घटकों का एक मज़ाक उड़ाया संस्करण लोड करने के लिए कोशिश की है, लेकिन पता नहीं कैसे:

लेकिन जब मैं परीक्षण मैं निम्नलिखित टेम्पलेट त्रुटि मिलती है की स्थापना की, सभी तीन घटकों के लिए बार-बार करने के लिए - मैंने जो उदाहरण देखा है, वे केवल माता-पिता को ओवरराइड करते हैं और बाल घटकों का भी उल्लेख नहीं करते हैं। तो मैं इसे करने के बारे में कैसे जा सकता हूँ?

उत्तर

13

आम तौर पर, यदि आपके पास उस घटक के दृश्य के अंदर उपयोग किया गया घटक है जिसका आप परीक्षण कर रहे हैं और आप उन घटकों को घोषित नहीं करना चाहते हैं, क्योंकि वे ** से बचने के लिए अपनी निर्भरताएं ले सकते हैं, कुछ ज्ञात तत्व नहीं है: ** त्रुटि आपको NO_ERRORS_SCHEMA का उपयोग करना चाहिए।

import { NO_ERRORS_SCHEMA }   from '@angular/core'; 

TestBed.configureTestingModule({ 
     declarations: declarations, 
     providers: providers 
     schemas:  [ NO_ERRORS_SCHEMA ] 
    }) 

डॉक्स के आधार पर:

परीक्षण मॉड्यूल के स्कीमा मेटाडाटा को NO_ERRORS_SCHEMA जोड़े गैर मान्यता प्राप्त तत्वों और विशेषताओं की अनदेखी करने के संकलक बताने के लिए। अब आपको अप्रासंगिक घटकों और निर्देशों की घोषणा नहीं करनी है।

अधिक इस पर: https://angular.io/docs/ts/latest/guide/testing.html#!#shallow-component-test

+1

आप जानते हैं कि मैं पर्यवेक्षण परीक्षण में देखने के लिए उस परीक्षण पृष्ठ पर था और उस हिस्से को कभी नहीं देखा। धन्यवाद - यह एक अच्छा पढ़ा गया था, हालांकि मेरी इच्छा है कि मुझे पहले मिल गया था !! अपने उत्तर को स्वीकार करना क्योंकि यह – Katana24

+1

से बहुत आसान है, यह वास्तव में एक खराब समाधान है क्योंकि यह अन्य संभावित मुद्दों को अस्पष्ट करता है और इसलिए परीक्षण कोड के उद्देश्य के विपरीत है। अर्नुद पी ने एक अच्छा जवाब दिया। – user5080246

4

मैंने इस प्रश्न को पोस्ट किया ताकि मैं एक उत्तर पोस्ट कर सकूं क्योंकि मैंने एक या दो दिन के लिए संघर्ष किया था। यहाँ कैसे आप यह कर दिया गया है:

let declarations = [ 
    ProductSelectedComponent, 
    ProductSettingsComponent, 
    ProductEditorComponent, 
    ProductOptionsComponent 
]; 

beforeEach(() => { 
     TestBed.configureTestingModule({ 
      declarations: declarations, 
      providers: providers 
     }) 
     .overrideComponent(ProductSettingsComponent, { 
      set: { 
       selector: 'product-settings', 
       template: `<h6>Product Settings</h6>` 
      } 
     }) 
     .overrideComponent(ProductEditorComponent, { 
      set: { 
       selector: 'product-editor', 
       template: `<h6>Product Editor</h6>` 
      } 
     }) 
     .overrideComponent(ProductOptionsComponent, { 
      set: { 
       selector: 'product-options', 
       template: `<h6>Product Options</h6>` 
      } 
     }); 

     fixture = TestBed.createComponent(ProductSelectedComponent); 
     cmp = fixture.componentInstance; 
     de = fixture.debugElement.query(By.css('section')); 
     el = de.nativeElement; 
    }); 

आप श्रृंखला के लिए बच्चे घटकों से प्रत्येक के लिए overrideComponent समारोह है।

+0

मुझे लगता है कि पहले त्रुटि अधिभावी, तो आप सिर्फ उन घटकों, जो आपको किसी भी तरह से किया है की घोषणा करने के लिए आवश्यक था द्वारा तय नहीं किया गया है By.css('app-child-component') उपयोग कर सकते हैं, तो अधिभावी है व्यर्थ जब तक आपको वास्तव में इसकी आवश्यकता नहीं है – Milad

+0

@ मिलाद जो सच है लेकिन मेरे मामले में, जिसमें मैंने शामिल नहीं किया है, यह है कि उन घटकों की सेवाओं पर अपनी निर्भरता है जो उन्हें उनके लिए शामिल करने की आवश्यकता होगी। क्योंकि मुझे केवल इस घटक का परीक्षण करने की परवाह है और दूसरों के बारे में बहुत ही बुनियादी निर्माण स्तर से परे परवाह नहीं है, मैं उन्हें खुशी से ओवरराइड कर सकता हूं – Katana24

25

NO_ERRORS_SCHEMA के बारे में सावधान। आइए डॉक्स के दूसरे भाग का उद्धरण दें:

NO_ERRORS_SCHEMA के साथ शैलो घटक परीक्षण जटिल टेम्पलेट्स के यूनिट परीक्षण को बहुत सरल बनाते हैं। हालांकि, संकलक अब आपको गलत वर्तनी या दुरुपयोग घटकों और निर्देशों जैसी गलतियों पर अलर्ट नहीं करता है।

मुझे लगता है कि यह परीक्षण एक परीक्षा लिखने के प्रयोजनों के विपरीत है। और भी इतना है कि बुनियादी घटक का नकल करना मुश्किल नहीं है।

एक दृष्टिकोण अभी तक यहां नहीं बताई उन्हें config समय में घोषित करने के लिए बस है:

@Component({ 
    selector: 'product-settings', 
    template: '<p>Mock Product Settings Component</p>' 
}) 
class MockProductSettingsComponent {} 

@Component({ 
    selector: 'product-editor', 
    template: '<p>Mock Product Editor Component</p>' 
}) 
class MockProductEditorComponent {} 

... // third one 

beforeEach(() => { 
    TestBed.configureTestingModule({ 
     declarations: [ 
     ProductSelectedComponent, 
     MockProductSettingsComponent, 
     MockProductEditorComponent, 
     // ... third one 
     ], 
     providers: [/* your providers */] 
    }); 
    // ... carry on 
}); 
+0

मैं इनपुट और आउटपुट के साथ बाल घटकों का परीक्षण करने के लिए ऐसा कुछ उपयोग कर रहा हूं, और यह सत्यापित करने के लिए यह बहुत अच्छा है कि बाइंडिंग दोनों तरीकों से काम कर रही हैं, हालांकि, यह "असली" में एक इनपुट प्रॉपर्टी के नाम के रूप में बिट-रॉट के प्रवण है। बाल घटक परीक्षण विफल होने का कारण नहीं बनेंगे। मुझे आश्चर्य है कि असली बाल घटक के आधार पर गतिशील मॉक प्रकार उत्पन्न करना संभव है, किसी भी तरह से इसकी टिप्पणियों का निरीक्षण करके। चूंकि प्रत्येक बच्चे के घटक पर निर्भरता इंजेक्शन का अज्ञात सेट हो सकता है, इसे केवल प्रकार के आधार पर कुछ होना चाहिए, न कि बच्चे घटक – Soraz

+0

का तत्काल संस्करण नहीं, मुझे लगता है कि उस मामले में आपको क्या करना है बच्चे के घटक को भी देखें। दस्तावेज़ों में एक [भाग इनपुट और आउटपुट का परीक्षण करने के लिए समर्पित है] (https://angular.io/guide/testing#test-a-component-with-inputs-and-outputs), जहां आप उम्मीद कर सकते हैं कि आपको क्या चाहिए। अगर मैं सही ढंग से समझता हूं, तो आप शायद [वह भाग जो सीधे अनुसरण करेंगे] (https://angular.io/guide/testing#test-a-component-inside-a-test-host-component) भी पसंद करेंगे। –

+0

अच्छा, उदाहरण दूसरी तरफ जाता है। अपने माता-पिता के खिलाफ बाध्यकारी घटकों का परीक्षण कैसे करें। यह आपकी मदद नहीं करता है यदि आपके पास 4 बाल घटकों के साथ मूल घटक है, और आप अलगाव में मूल घटक का परीक्षण करना चाहते हैं, क्योंकि आपको अभी भी मैन्युअल रूप से हल करने और सभी बाल घटक निर्भरताओं को प्रदान करने की आवश्यकता होगी, या मैन्युअल रूप से एक नकली संस्करण बनाए रखना होगा प्रत्येक बच्चे घटक। आदर्श रूप में, मैं एक घटक को दो में विभाजित कर सकता हूं, एक बेस डायरेक्टिव जिसमें इनपुट और आउटपुट है, और एक विरासत संस्करण घटक जो टेम्पलेट प्रदान करता है, लेकिन यह काम नहीं करेगा क्योंकि उन्हें एक ही चयनकर्ता होना होगा। – Soraz

0

मिले एक लगभग पूर्ण समाधान है, अगर किसी को एक घटक refactors कि यह भी सही ढंग से त्रुटियों फेंक देते हैं।

npm install mock-component 

अब आप अपने .spec.ts में आप कर सकते हैं

import { MockComponent } from 'mock-component'; 
import { ChildComponent } from './child.component.ts'; 
... 
    beforeEach(
async(() => { 
    TestBed.configureTestingModule({ 
    imports: [FormsModule, ReactiveFormsModule, RouterTestingModule], 
    declarations: [ 
     ComponentUnderTest, 
     MockComponent(ChildComponent), 
     ... 

यह एक नई अज्ञात घटक, @Input() एक ही चयनकर्ता और @Output() ChildComponent का गुण है कि बनाता है, लेकिन कोई कोड संलग्न नहीं है।

मान लें आपके ChildComponent एक @Input() childValue: number है, कि, परीक्षण के तहत अपने घटक में ही है <app-child-component [childValue]="inputValue" />

केवल नकारात्मक पक्ष यह है मैं अब तक पाया है, कि आप अपने परीक्षण में By.directive(ChildComponent) उपयोग नहीं कर सकते, के रूप में, है परिवर्तन टाइप किया, लेकिन आप की तरह तो

it('sets the right value on the child component`,()=> { 
    component.inputValue=5; 
    fixture.detectChanges(); 
    const element = fixture.debugElement.query(By.css('app-child-component')); 
    expect(element).toBeTruthy(); 

    const child: ChildComponent = element.componentInstance; 

    expect(child.childValue).toBe(5); 
}); 
संबंधित मुद्दे