【问题标题】:Angular 2: How to unit test tabs component with tightly coupled parent and child componentsAngular 2:如何使用紧密耦合的父子组件对标签组件进行单元测试
【发布时间】:2018-01-06 04:13:22
【问题描述】:

我跟着Thoughtram's article创建了一个标签组件。

它基本上创建了两个组件:TabTabs。这里Tabs 组件是Tab 组件的父/主机,用于将所有选项卡组合在一起。我需要能够对这两个组件进行单元测试。

我想到的测试场景是:

  • Tab 必须注入它所依赖的父组件:Tabs
  • 默认情况下必须选择第一个选项卡。
  • Tabs 的函数 addTab 必须从 Tab 组件调用一次
  • 函数selectTab必须在点击相应选项卡时被调用,该函数又应该将选项卡设置为活动状态,所有其他选项卡设置为非活动状态。
  • 我想可能还有更多...

问题是我不知道如何测试这些东西以及什么应该是一个好的方法来做到这一点。我一直在阅读角度文档,但我无法理解这种情况。有人可以帮忙吗?

【问题讨论】:

    标签: javascript angular unit-testing jasmine


    【解决方案1】:

    单元测试已经在名称中。您只想测试一个单元。您的Tab 组件应单独测试。它与您的Tabs 组件没有真正的依赖关系。

    所以测试可能看起来像这样:

    @Component({
        template: `<tab tabTitle="tabTitle">{{ content }}</tab>`
    })
    class TestHostComponent {
         @ViewChild(TabComponent) tab: TabComponent;
         content: string = '';
         tabTitle: string = 'foo';
    }
    
    describe('TabComponent', function () {
        let fixture: ComponentFixture<TestHostComponent>;
        let comp: TestHostComponent;
        let debugElement: DebugElement;
    
        beforeEach(async(() => {
            TestBed.configureTestingModule({
                declarations: [ TestHostComponent ]
            }).compileComponents();
        }));
    
        beforeEach(() => {
            fixture = TestBed.createComponent(TestHostComponent);
            comp = fixture.componentInstance;
            debugElement = fixture.debugElement;
            fixture.detectChanges();    // ngOnInit
        });
    
        it('should create the component', () => expect(comp).toBeDefined() );
    
        it('should change the title', () => {
            expect(comp.tab.tabTitle).toBe('foobar');
            comp.tabTitle = 'bar';
            fixture.detectChanges();
            expect(comp.tab.tabTitle).toBe('bar');
        });
    
        it('should change the content', () => {
            comp.content = 'foobar';
            fixture.detectChanges();
            let tabTextContent: string = debugElement.query(By.css('tab')).nativeElement.textContent;
            expect(tabTextContent).toBe('foobar');
        });
    });
    

    当然,如果你真的想同时测试两者,你可以用类似的方法,只需将你的 TestHost 的模板更改为类似

    @Component({
         template: `<tabs><tab tabTitle="tabTitle">{{ content }}</tab></tabs>`
    });
    

    并调整您的ViewChilds 以及处理ngOnInitAfterViewInit 的方式。

    但正如我所说,不建议这样做(您可以在您的 TabsComponent 测试中执行此操作,以检查您的 Tabs 是否正常工作,如果他们有一个或多个 TabComponents 内部,但不是在您的 @987654331 @)。

    仅仅因为它使测试变得更加困难和更加具体(您必须控制 angulars 生命周期挂钩等),每个测试集合的大小都会变得混乱(这很糟糕,因为您必须更改大部分内容您对组件进行更改的时间),并且由于它是一个独立的组件,因此您可以在无论如何都希望将其包含在其他地方并且必须涵盖这一点的场景中运行。

    希望能帮到你。

    【讨论】:

    • 嘿!这让事情变得非常清楚。非常感谢:)
    • 嘿@lexith,是不是像'should change the title' 这样的测试就像测试输入绑定是否有效? Angular 的人一定已经完成了这种测试。我们应该测试更好的东西吗?
    • 当然,这只是一个例子。您当然想测试自己的功能,但可能有一些用例您想做这样的事情(例如,如果输入应该在更改或其他事情上被操纵......)。同样,只是一个例子:)
    猜你喜欢
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多