【问题标题】:Error when testing a component which uses templateUrl测试使用 templateUrl 的组件时出错
【发布时间】:2017-11-08 19:30:48
【问题描述】:

我可以在测试输出中看到 console.log(dummyComponentInstance); 被调用并评估为 undefined

另外,console.log('beforeEach done'); 永远不会被记录。

dummy.component.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { DummyComponent } from './dummy.component';

describe('DummyComponent', () => {

  let dummyComponentInstance: DummyComponent;
  let fixture: ComponentFixture<DummyComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [DummyComponent]
    })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(DummyComponent);
        dummyComponentInstance = fixture.componentInstance;
        console.log('beforeEach done');
      });
  }));

  it('should work', () => {
    console.log(dummyComponentInstance);
    expect(dummyComponentInstance instanceof DummyComponent).toBe(true, 'should create DummyComponent');
  });
});

dummy.component.ts

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

@Component({
  selector: 'dummy',
  templateUrl: './dummy.component.html'
})
export class DummyComponent {
  public initialized = false;
}

运行测试后出错:

07 06 2017 13:27:09.187:INFO [launcher]: Starting browser PhantomJS
07 06 2017 13:27:09.437:INFO [PhantomJS 2.1.1 (Linux 0.0.0)]: Connected on socket 4Vq49vX24cDAIZfjAAAA with id 34827962
LOG: undefined
PhantomJS 2.1.1 (Linux 0.0.0) DummyComponent should work FAILED
    invokeTask@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:605:36
    onInvokeTask@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:154:49
    invokeTask@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:604:48
    runTask@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:372:57
    drainMicroTaskQueue@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:765:42
    run@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:17951:29
    /tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:17964:31
    flush@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:17813:11
    resolvePromise@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:951:78
    resolvePromise@/tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:921:31
    /tmp/karma-typescript-bundle-27168S216WqzJyZ6g.js:998:31
    Expected false to be true, 'should create DummyComponent'.
    src/app/dummy.component.spec.js:21:98

【问题讨论】:

  • 你试过@Mathias Rodriguez 写的关于beforeEach 的建议吗?并添加一个beforeEach 而不添加async

标签: angular unit-testing typescript


【解决方案1】:

你介意尝试一下吗?

@angular/core/testing 导入fakeAsynctick。 在测试用例中移动.then() 正文,并在那里使用fakeAsync(),让我知道它是怎么回事。

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [DummyComponent]
    })
    .compileComponents();
}));

it('should work', fakeAsync(() => {
    fixture = TestBed.createComponent(DummyComponent);
    dummyComponentInstance = fixture.componentInstance;
    tick();

    expect(dummyComponentInstance instanceof DummyComponent).toBe(true, 'should create DummyComponent');
}));

希望这对你有用!

【讨论】:

【解决方案2】:

所以有几件事,这可能只是我的困惑。 dummy.component.html 真的存在吗?

当你打电话时

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [DummyComponent]
    })
      .compileComponents()
      .then(() => {
        fixture = TestBed.createComponent(DummyComponent);
        dummyComponentInstance = fixture.componentInstance;
        console.log('beforeEach done');
      });
  }));

您基本上是在说“嘿,我有一些文件需要您获取,这是一个异步操作,请编译该模板,然后创建我的夹具。

如果该 html 文件不存在......它将在您的测试平台配置期间失败。我问是因为您没有显示该文件。

我将您的代码放到了我的测试项目中,它在一个空模板上运行良好。它也适用于空的 templateUrl 文件。

如果您还没有该文件,或者您不打算测试该文件,则可以通过同时避免使用fixture =TestBed.createComponent(DummyComponent) 来节省管理费用。它非常昂贵(你说的是 800~ms 与 15ms),因为它创建了许多额外的(和强大的)功能(比如将你的模板编译为一种影子 DOM,据我所知)。

如果您确实有一个 dummy.component.html 文件,并且其中包含动态模块不知道如何解释的元素,那么您可以从 @angular/core 导入 NO_SCHEMA_ERRORS 并将其放入您的配置 TestBed 中:

...
schemas: [NO_SCHEMA_ERRORS]
...

或者您可以只教测试平台如何提供这些元素(通常导入这些部分。但同样,这不是您的问题。您的问题似乎是 dummy.component.html 不存在。

希望这会有所帮助。

【讨论】:

  • 关闭,问题是 OP 错过了将 FormsModule 添加到配置部分。
【解决方案3】:

由于我的templateUrl 文件包含需要在我的TestBed 对象中设置的角度形式..

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [PageFormComponent],
    imports: [FormsModule]
  }).compileComponents()
    .then(() => {
      fixture = TestBed.createComponent(PageFormComponent);
      pageFormComponentInstance = fixture.componentInstance;
    });
}));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多