单元测试错误:无法从同步测试中调用 Promise.then
Posted
技术标签:
【中文标题】单元测试错误:无法从同步测试中调用 Promise.then【英文标题】:Unit test error: Cannot call Promise.then from within a sync test 【发布时间】:2017-08-28 10:22:06 【问题描述】:我开始研究 Angular 2 应用程序的单元测试,但即使是最简单的示例,我也遇到了困难。我只想运行一个简单的测试,看看它是否有效,基本上我想要的是将标题页中的值与测试中的值进行比较。
这是我遇到的错误,但我看不出错误来自哪里,因为一切看起来都与我同步。
错误:错误:无法从同步测试中调用 Promise.then。
单元测试:
import ComponentFixture, TestBed from '@angular/core/testing';
import By from '@angular/platform-browser';
import DebugElement, Input from '@angular/core';
import ToDoComponent from './todo.component';
import FormsModule from '@angular/forms';
describe(("test input "),() =>
let comp: ToDoComponent;
let fixture: ComponentFixture<ToDoComponent>;
let de: DebugElement;
let el: htmlElement;
beforeEach(() =>
TestBed.configureTestingModule(
declarations: [ ToDoComponent ],
imports: [ FormsModule ]
)
.compileComponents();
);
fixture = TestBed.createComponent(ToDoComponent);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css("h1"));
el = de.nativeElement;
it('should display a different test title', () =>
comp.pageTitle = 'Test Title';
fixture.detectChanges();
expect(el.textContent).toBe('Test Title423');
);
);
我的组件:
import Component from "@angular/core";
import Note from "app/note";
@Component(
selector : "toDoArea",
templateUrl : "todo.component.html"
)
export class ToDoComponent
pageTitle : string = "Test";
noteText : string ="";
noteArray : Note[] = [];
counter : number = 1;
removeCount : number = 1;
addNote() : void
if (this.noteText.length > 0)
var a = this.noteText;
var n1 : Note = new Note();
n1.noteText = a;
n1.noteId = this.counter;
this.counter = this.counter + 1;
this.noteText = "";
this.noteArray.push(n1);
removeNote(selectedNote : Note) :void
this.noteArray.splice(this.noteArray.indexOf(selectedNote),this.removeCount);
【问题讨论】:
【参考方案1】:将变量初始化移到 beforeEach 中。
您不应该从 TestBed 中取出东西或管理 describe
范围内的夹具或组件。您应该只在测试运行范围内执行这些操作:在 beforeEach
/beforeAll
、afterEach
/afterAll
或 it
内。
describe(("test input "), () =>
let comp: ToDoComponent;
let fixture: ComponentFixture<ToDoComponent>;
let de: DebugElement;
let el: HTMLElement;
beforeEach(async(() =>
TestBed.configureTestingModule(
declarations: [ToDoComponent],
imports: [FormsModule]
)
.compileComponents();
));
beforeEach(() =>
fixture = TestBed.createComponent(ToDoComponent);
comp = fixture.componentInstance;
de = fixture.debugElement.query(By.css("h1"));
el = de.nativeElement;
)
it('should display a different test title', () =>
comp.pageTitle = 'Test Title';
fixture.detectChanges();
expect(el.textContent).toBe('Test Title423');
);
);
另见
https://angular.io/docs/ts/latest/guide/testing.html#!#waiting-compile-components【讨论】:
这个例子是正确的,但是评论没有解决你遇到的问题。 compileComponents() 是一个读取 HTML 模板的异步函数,因此它需要异步测试区(由第一个 beforeEach 中的 async() 设置)。第二个 beforeEach 保证仅在第一个完成后运行(有点不明显,但很有帮助)。另一种选择是在 compileComponents 上使用 .then(),因为它返回一个承诺。请注意,如果您使用 webpack (Angular CLI) 或其他一些机制来捆绑组件模板,则无需调用 compileComponents()。 就我而言,在describe
块而不是it
块中执行测试代码时出现此错误。
节省了一天!【参考方案2】:
由于不同的原因,我得到了同样的错误。我在describe
块中放置了一个TestBed.get(Dependency)
调用。修复将其移至 it
块。
错误:
describe('someFunction', () =>
const dependency = TestBed.get(Dependency); // this was causing the error
it('should not fail', () =>
someFunction(dependency);
);
);
固定:
describe('someFunction', () =>
it('should not fail', () =>
const dependency = TestBed.get(Dependency); // putting it here fixed the issue
someFunction(dependency);
);
);
【讨论】:
TestBed.get()
方法已被弃用,因为应该使用 Angular 9.0.0,TestBed.inject()
。以上是关于单元测试错误:无法从同步测试中调用 Promise.then的主要内容,如果未能解决你的问题,请参考以下文章
由于 otest 错误,无法从命令行运行 Xcode 单元测试