【问题标题】:Angular2 testing. Promise never resolved inside TestBed.compileComponentsAngular2 测试。 Promise 从未在 TestBed.compileComponents 中解决
【发布时间】:2017-04-22 07:17:37
【问题描述】:

我目前正在为我的 Angular2 组件中的一个模块编写一个测试模块,该模块使用 templateUrl 属性,因此需要在测试之前进行 TestBed.compileComponents 异步调用以进行编译。

我遇到的问题是,promise 回调 (then) 函数中的任何内容都没有运行...好像 promise 没有解决一样。

这是我的代码。

模块:

import { Component } from "@angular/core";

@Component({
    selector: 'categories-component',
    templateUrl: '/app/views/catalog/categories/categories-dashboard.html',
    moduleId: module.id
})

export class CategoriesComponent {
    title: 'Categories;
}

HTML 模板:

<h1>{{ title }}</h1>

以及测试模块:

import {TestBed, ComponentFixture, ComponentFixtureAutoDetect, async} from "@angular/core/testing";
import { By} from "@angular/platform-browser";
import { CategoriesComponent } from "../../../../components/catalog/categories/CategoriesComponent";
import { DebugElement } from "@angular/core";

let comp:    CategoriesComponent;
let fixture: ComponentFixture<CategoriesComponent>;
let de:      DebugElement;
let el:      HTMLElement;

describe('CategoriesComponent', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [ CategoriesComponent ],
            providers: [
                { provide: ComponentFixtureAutoDetect, useValue: true }
            ]
        });
    });

    it('should display original title', () => {
        TestBed.compileComponents()
            .then(() => {
                fixture = TestBed.createComponent(CategoriesComponent);

                comp = fixture.componentInstance; // BannerComponent test instance

                // query for the title <h1> by CSS element selector
                de = fixture.debugElement.query(By.css('h1'));
                el = de.nativeElement;

                expect(el.textContent).toContain(comp.title);
            });

});

});

如您所见,在我的测试中,我调用 compileComponents 来异步编译测试模块,然后在回调中创建测试组件的夹具和实例。这些都没有运行,我在其中添加了断点,它永远不会触发。

谁能指出我在这里做错了什么?

谢谢!

【问题讨论】:

    标签: javascript unit-testing angular testing promise


    【解决方案1】:

    因为测试是同步的

    it('...', () => {
    })
    

    这里的回调执行,测试在回调函数执行后完成。

    但问题是你的所有代码都在异步回调中

    it('...', () => {
      TestBed.compileComponents().then(() => {
        // asynchronous
        // code not executed
      })
    })
    

    所以在测试完成之前,异步代码永远不会被执行。

    这可以通过多种方式处理。可以使用原生茉莉done回调

    it('...', (done) => {
      TestBed.compileComponents().then(() => {
        /// do stuff
    
        done();
      })
    })
    

    这里,jasmine 给你传递了一个回调函数。完成所有异步操作后调用它是您的工作。

    另一种方法是使用 Angular async

    import { async } from '@anguar/core/testing';
    
    it('...', async(() => {
      TestBed.compileComponents().then(() => {
    
      })
    }))
    

    这样做是将测试包装在测试区域中,该区域跟踪所有异步任务,并在所有异步任务完成后完成测试。在 jasmine 环境下,测试区实际上会在异步任务完成后调用 jasminedone 回调。

    【讨论】:

    • 您好,感谢您的回答。我确实认为是这种情况,但是当我使用这些解决方案的枯萎时,我收到以下错误。错误:超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调。
    • 我不知道。我已经多次看到该错误。我不记得是什么问题了。您是否在 Google 上搜索过错误(与 Angular 2 和业力有关)?
    • 尝试将模板移动到@Component.template 并摆脱templateUrl 并且不要调用compileComponents。看看它是否有效。如果它有效,那么这是compileComponents 的问题。虽然不确定是什么原因造成的。至少如果你把问题缩小到这个范围,它会缩小你的搜索范围
    • 太棒了。我会继续努力。至少我从你的回答中知道我在尝试使用 async() 函数时是正确的,所以感谢你的帮助。
    猜你喜欢
    • 1970-01-01
    • 2018-02-06
    • 2021-04-24
    • 2017-03-18
    • 1970-01-01
    • 2017-10-13
    • 2020-04-10
    • 1970-01-01
    相关资源
    最近更新 更多