fakeAsync 函数中的 tick() 不等待承诺解决

dan*_*ker 10 karma-jasmine angular

考虑这个服务函数,它检索单个任务并将结果包装在一个承诺中。

get(id: string): Promise<Task> {
    return new Promise((resolve, reject) => {
      this.tasks.findOne({_id: id}).exec(function (err, doc) {
        console.log("Getting task: ", doc);
        if (err)
          reject(err);
        else
          resolve(<Task>doc);
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

我为 get 函数编写了这个单元测试:

beforeEach(() => {
    const injector = TestBed.configureTestingModule({
        providers: [TaskService, Logger]
    });
    subject = injector.get(TaskService);
    var Datastore = require('nedb');
    db = new Datastore({filename: 'test'});

     subject.setDBConnection(db);
    task = new Task();
    task.title = 'Test Task';
    task._id = "TEST";

    db.loadDatabase();

    db.insert(task);

});


it('returns existing record', fakeAsync(() => {
  let r = null;

  subject.get('TEST').then((doc) => {
    r = doc;
    console.log(this.result);

  });

  tick();
  console.log("expectation run", r);
  expect(result).toBeDefined();
  expect(r.title).toEqual('Test Task');

}));
Run Code Online (Sandbox Code Playgroud)

出于某种原因, fakeAsync() 和 tick() 函数没有完成它们的工作,因为控制台输出在then块将结果打印到控制台之前显示“期望运行” 。(典型的异步代码执行)。

我究竟做错了什么?如何修复此代码以等待承诺完成?

我正在关注此页面上的示例。我认为这个问题是由get调用异步函数本身然后返回一个必须在测试中解决的承诺造成的。虽然我不明白为什么这不可行,因为文档中的示例以简化的方式执行完全相同的操作,例如:

it('should test some asynchronous code', fakeAsync(() => {
    let flag = false;
    setTimeout(() => { flag = true; }, 100);
    expect(flag).toBe(false); // PASSES
    tick(50);
    expect(flag).toBe(false); // PASSES
    tick(50);
    expect(flag).toBe(true); // PASSES
}));
Run Code Online (Sandbox Code Playgroud)

umu*_*sen 0

您尚未指定模拟时间流逝的时间。

例如,tick(500)将等待 500 毫秒。

 get(id: string): Promise<any> {
    return new Promise((resolve) => setTimeout(resolve, 500));
 }
Run Code Online (Sandbox Code Playgroud)

这可以通过以下方式进行测试:

  it('returns existing record', fakeAsync(() => {
    component.get('TEST').then((x) => {
      console.log('get finished');
    });

    tick(550); // wait 501 ms 

    console.log('expectation run');

    flush();
  }));
Run Code Online (Sandbox Code Playgroud)

打印

// get finished
// expectation run
Run Code Online (Sandbox Code Playgroud)

就您而言,您需要猜测运行需要多长时间TaskService才能保证正确的事件链。

我建议使用await,它将等到承诺解决后再执行下一行代码。

  it('returns existing record', async () => {
    await component.get('TEST');
    console.log('expectation run');
  });
Run Code Online (Sandbox Code Playgroud)