Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular Async/FakeAsync是否等待。然后在spec块中或仅在组件/类中等待它';什么是测试?_Angular_Unit Testing_Asynchronous_Jasmine - Fatal编程技术网

Angular Async/FakeAsync是否等待。然后在spec块中或仅在组件/类中等待它';什么是测试?

Angular Async/FakeAsync是否等待。然后在spec块中或仅在组件/类中等待它';什么是测试?,angular,unit-testing,asynchronous,jasmine,Angular,Unit Testing,Asynchronous,Jasmine,我有点担心我的一个karma jamine测试仍然通过了这个代码 // before each above comp = fixture.componentInstance // This spec passes it(`should not pass because async activity?`, () => { comp.router.navigate(['home']).then(() => { expect(true).toBe(true); /

我有点担心我的一个karma jamine测试仍然通过了这个代码

// before each above
comp = fixture.componentInstance

// This spec passes
it(`should not pass because async activity?`, () => {
    comp.router.navigate(['home']).then(() => {
        expect(true).toBe(true); // should not execute?
        // Should only execute if I placed done()?
    });
});
当我们使用async/fakeAsync包装器时,我认为使用.then()是可以的

示例代码取自angular文档:

  it('should show quote after getQuote promise (async)', async(() => {
    fixture.detectChanges();

    fixture.whenStable().then(() => { // wait for async getQuote
      fixture.detectChanges();        // update view with quote
      expect(el.textContent).toBe(testQuote);
    });
  }));
尽管此代码也在没有任何包装的情况下通过:

it(`should also not pass?`, () => {
    fixture.whenStable().then(() => {
      expect(true).toBe(true); // But it passes!! : /
    });
  });
因此,这让我相信,可能async/fakeAsync包装器只用于拦截我们正在测试的组件/类中的异步活动,而不用于我们正在测试的规范

有人能验证为什么.then异步代码在jasmine规范上执行时没有done()函数吗?为什么我们可以这样做?不添加done()函数真的安全吗

更新 感谢您发表以下评论:

我做了一个预期(假)。是(真)和


因此,我很高兴看到.whenStable()在没有包装器的情况下跳过then。还有一点与router有关。then()

async是一个包装器,用于向调用该函数的人发出警告,警告他们该函数包含异步代码。恐怕我不能真正解释在测试中使用异步有什么区别,但是我想我可以解释您对done函数的困惑

首先让我澄清一点,你的第一次和第三次考试总是会通过的。请记住,空测试通过:

it(`passes`, () => {
});
因此,如果您添加了一个if语句,其中expect应该通过,那么无论if语句是否为true,测试都将通过

it(`still passes`, () => {
  if (21 < 42) {
    expect(true).toBe(true);
  }
});
记住Jasmine会在5秒后暂停任何测试,除非您更改Jasmine.DEFAULT\u timeout\u INTERVAL


您希望使用done函数让Jasmine知道您的测试已经完成。我不确定是否真的需要它,但我想可能有一种说法认为它可以使带有回调函数的测试更具可读性。

async
fakeAsync
依赖于区域,它们等待异步代码在属于规范的区域中进行计算。承诺是在组件内部还是在规范函数内部创建的,只要它位于区域内,这都无关紧要

这个

之所以有效,是因为Jasmine经过修补,可以与Zone.js一起使用,并且支持
async
/
fakeAsync
帮助程序,并导致与原始行为不兼容的行为。当履行的承诺与
链接时,则
,即使没有
异步
,也可能检测到期望并保留规范顺序,但不应依赖此行为

这个

将在Zone.js中失败

如果茉莉花没有修补好,这两个例子都无法检测出人们的期望

一个好的做法是始终从异步规范返回承诺(承诺返回时不使用
async
/
fakeAsync
助手在Jasmine 2.7及更高版本中受支持):


OP中描述的行为非常特定于Angular async/fakeAsync助手,事实上Jasmine/Mocha由Zone.js修补以支持它们。帮助者被介绍来摆脱原来的Jasmine工作流和
done
callback。@estus那么,当你看到一篇帖子说我想问(a)因为我看到(b)和(c)正在发生,但你对(a)知之甚少,但你确实理解(b)和(c)的原因时,你会有什么建议我现在已经阅读了async/fakeAsync应该做什么,但在我的测试中,它们似乎没有这种效果。看起来我有时间问我自己的问题。我会把问题留给那些知道A,B& C的用户,或者认为这是一个了解A的机会,或者像你一样回答B& C。任何选项都可能对OP有效。即使没有,答案可能对有相关问题的人有用。至于fakeAsync,它是jasmine.clock的一个有魔力的角度伪异步替代品。关于使用
comp.router.navigate(['home'])
的第一个代码段,由于没有检测到断言,所以不完全清楚它是否通过。一个好习惯是使用
expect(true)使测试最初失败。toBe(false)
以检测误报。感谢您的回答,重新整理有关区域的信息,这真的很有帮助。:)
it(`still passes`, () => {
  if (21 < 42) {
    expect(true).toBe(true);
  }
});
it(`passes because done in wrong place`, (done) => {
  setTimeout(() => {
     expect(false).toBe(true);
  }, 500);
  done();
});

it(`correctly does not pass as expect trigered`, (done) => {
  setTimeout(() => {
     expect(false).toBe(true);
     done();
    }, 500);
});
  it(`passes with Zone.js`, () => {
    Promise.resolve().then(() => {
      expect(true).toBe(true);
    });
  });
  it(`fails with Zone.js`, () => {
    new Promise(resolve => setTimeout(resolve)).then(() => {
      expect(true).toBe(true);
    });
  });
it(`should not pass because async activity?`, async () => {
    await comp.router.navigate(['home']);
    expect(true).toBe(true);
});