Angular 2 Unit-Testdaten, die von der übergeordneten Komponente an die untergeordnete Komponente übergeben werden

Ich habe eine Frage dazu, wie ich (die wenigen) Beispiele für das Testen von Daten gesehen habe, die von einer übergeordneten Komponente in eine untergeordnete Komponente übertragen wurden. Derzeit in der Angular2 docs, sie testen, ob Daten von einer übergeordneten Komponente an ein untergeordnetes Element von @ übergeben wurdeinspektion der dom-Werte der untergeordneten Komponente. Das Problem, das ich bei diesem Ansatz habe, ist, dass die übergeordnete Spezifikation gezwungen wird, die HTML-Struktur der untergeordneten Komponente zu kennen. Der Job der übergeordneten Komponente ist nurUm Daten an das Kind zu übergeben. Ein Beispiel..

Ich habe eine Story-Komponente wie folgt:

'use strict';

import {Component, OnInit, Input} from '@angular/core';
import {StoryService} from '../../services/story.service';
import {StoryModel} from '../../models/story-model';
import {AlbumCover} from './album-cover/album-cover';
import {Author} from "./author/author";
import {StoryDuration} from "./story-duration/story-duration";

@Component({
    selector: 'story',
    templateUrl: 'build/components/story/story.html',
    providers: [StoryService],
    directives: [AlbumCover, Author, StoryDuration]
})

export class Story implements OnInit {
    @Input('id') id:number;
    public story:StoryModel;

    constructor(private storyService:StoryService) {}

    ngOnInit() {
        this.getStory();
    }

    private getStory() {
        this.storyService.getStory(this.id).subscribe(story => this.story = story);
    }
}

Notice wie es ein @ hAlbumCover Komponentenabhängigkeit imdirectives Array im@Component Dekorateur.

Hier ist meine Story-Vorlage:

<div *ngIf="story">
    <album-cover [image]="story.albumCover" [title]="story.title"></album-cover>
    <div class="author-duration-container">
        <author [avatar]="story.author.avatar" [name]="story.author.name"></author>
        <story-duration [word-count]="story.wordCount"></story-duration>
    </div>
</div>

Notice the<album-cover [image]="story.albumCover" [title]="story.title"></album-cover> Zeile, in der ich das @ binstory.albumCover von demStory controller zumimage Eigenschaft desAlbumCover. Das funktioniert alles perfekt. Nun zum Test:

import {provide} from '@angular/core';
import {beforeEach, beforeEachProviders, describe, expect, injectAsync, it, setBaseTestProviders, resetBaseTestProviders} from '@angular/core/testing';
import {HTTP_PROVIDERS} from '@angular/http';
import {BROWSER_APP_DYNAMIC_PROVIDERS} from "@angular/platform-browser-dynamic";
import {TEST_BROWSER_STATIC_PLATFORM_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS} from '@angular/platform-browser/testing';
import {ComponentFixture, TestComponentBuilder} from '@angular/compiler/testing';
import {Observable} from 'rxjs/Observable';

// TODO: this pattern of importing 'of' can probably go away once rxjs is fixed
// https://github.com/ReactiveX/rxjs/issues/1713
import 'rxjs/add/observable/of';

resetBaseTestProviders();
setBaseTestProviders(
    TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
    [BROWSER_APP_DYNAMIC_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS]
);

import {Story} from './story';
import {StoryModel} from '../../models/story-model';
import {StoryService} from '../../services/story.service';

var mockStory = {
    id: 1,
    title: 'Benefit',
    albumCover: 'images/placeholders/story-4.jpg',
    author: {
        id: 2,
        name: 'Brett Beach',
        avatar: 'images/placeholders/author-1.jpg'
    },
    wordCount: 4340,
    content: '<p>This is going to be a great book! I <strong>swear!</strong></p>'
};

class MockStoryService {
    public getStory(id):Observable<StoryModel> {
        return Observable.of(mockStory);
    }
}

describe('Story', () => {
    var storyFixture,
        story,
        storyEl;

    beforeEachProviders(() => [
        HTTP_PROVIDERS
    ]);

    beforeEach(injectAsync([TestComponentBuilder], (tcb:TestComponentBuilder) => {
        return tcb
            .overrideProviders(Story, [
                provide(StoryService, {
                    useClass: MockStoryService
                })
            ])
            .createAsync(Story)
            .then((componentFixture:ComponentFixture<Story>) => {
                storyFixture = componentFixture;
                story = componentFixture.componentInstance;
                storyEl = componentFixture.nativeElement;
                componentFixture.detectChanges();
            });
    }));

    describe(`ngOnInit`, () => {
        describe(`storyService.getStory`, () => {
            it(`should be called, and on success, set this.story`, () => {
                spyOn(story.storyService, 'getStory').and.callThrough();
                story.ngOnInit();
                expect(story.storyService.getStory).toHaveBeenCalled();
                expect(story.story.title).toBe('Benefit');
            });
        });
    });

    it('should not show the story component if story does not exist', () => {
        story.story = null;
        storyFixture.detectChanges();
        expect(storyEl.children.length).toBe(0);
    });

    it('should show the story component if story exists', () => {
        story.story = mockStory;
        storyFixture.detectChanges();
        expect(storyEl.children.length).not.toBe(0);
    });

    describe('story components', () => {
        beforeEach(() => {
            story.story = mockStory;
            storyFixture.detectChanges();
        });

        describe('album cover', () => {
            var element,
                img;

            beforeEach(() => {
                element = storyEl.querySelector('album-cover');
                img = element.querySelector('img');
            });

            it(`should be passed the story albumCover and title to the album cover component`, () => {
                expect(img.attributes.src.value).toBe(mockStory.albumCover);
                expect(img.attributes.alt.value).toBe(mockStory.title);
            });
        });

        describe('author', () => {
            var element,
                img,
                nameEl;

            beforeEach(() => {
                element = storyEl.querySelector('author');
                img = element.querySelector('img');
                nameEl = element.querySelector('.name');
            });

            it(`should be passed the author name and avatar`, () => {
                expect(img.attributes.src.value).toBe(story.story.author.avatar);
                expect(img.attributes.alt.value).toBe(story.story.author.name);
                expect(nameEl.innerText).toBe(story.story.author.name);
            });
        });

        describe('story duration', () => {
            var element;

            beforeEach(() => {
                element = storyEl.querySelector('.story-duration');
            });

            it(`should be passed the word count to generate the total read time`, () => {
                story.story.wordCount = 234234;
                storyFixture.detectChanges();
                expect(element.innerText).toBe(`852 min read`);
            });
        });
    });
});

Guck auf meindescribe('album cover'.... Die Art und Weise, wie ich diese Erwartung erfülle, ist, dass ich das @ find<album-cover> -Element, dann das @ find<img> tag drin, dann prüfe das<img>OM-Attribute von @. Für mich sollte diese Erwartung innerhalb des @ sealbum-cover.spec.ts - Nicht derstory.spec.ts.

Meine Frage is: Gibt es eine Möglichkeit zu testen, ob eine übergeordnete Komponente Daten an eine untergeordnete Komponente übergeben hat, ohne auf das Lesen von dom-Werten angewiesen zu sein?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage