【问题标题】:Unit test error: Cannot call Promise.then from within a sync test单元测试错误:无法从同步测试中调用 Promise.then
【发布时间】: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);
    }

}

【问题讨论】:

    标签: javascript unit-testing angular


    【解决方案1】:

    将变量初始化移到 beforeEach 中。

    您不应该从 TestBed 中取出东西或管理 describe 范围内的夹具或组件。您应该只在测试运行范围内执行这些操作:在 beforeEach/beforeAllafterEach/afterAllit 内。

    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');
      });
    
    });
    

    另见

    【讨论】:

    • 这个例子是正确的,但是评论没有解决你遇到的问题。 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()
    猜你喜欢
    • 1970-01-01
    • 2021-02-23
    • 2019-11-11
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 2011-05-05
    相关资源
    最近更新 更多