【问题标题】:Jasmine spies callThrough and callFakeJasmine 间谍 callThrough 和 callFake
【发布时间】:2021-07-13 22:23:07
【问题描述】:

我有一个场景,我想在调用回调后在 beforeEach 上调用 done()

我尝试这样做:

spyOn(scope, 'onAdmin').and.callThrough().and.callFake(function(){done()})

但我不确定我的行为是否正确。基本上我想要实现的是能够在每个回调完成后调用done()

更新:解决方法

scope.onAdminBackup = scope.onAdmin;
spyOn(scope, 'onAdmin').and.callFake(function(admin)  {

 scope.onAdminBackup();
 done() ;

})  

【问题讨论】:

  • 除了这个变通方法还有其他解决方案吗?
  • 这段代码是否会导致无限循环,因为scope.onAdminBackup() 调用scope.onAdmin 被伪造为调用scope.onAdminBackup() 等等

标签: javascript angularjs jasmine


【解决方案1】:

我从来没有将这些类型的函数链接在一起,因为在我看来它们似乎做相反的事情。您是说当我调用此方法时 -onAdmin - 在范围内正常调用它。这就是 jasmine 为我们提供的 callThrough 方法所做的。

但是你也链接了一个 callFake 方法,所以你说但实际上并没有调用它,而是调用这个假函数 - 非常矛盾。

如果你想在 onAdmin 方法上调用 spy,而不是让它被解雇,你希望它做其他事情——一些被嘲笑的事情——然后使用 .and.callFake(fn)。还要考虑到上面提到的@stefan - 不要调用函数 - callFake 只是想要一个函数作为参数,它会自行调用它。

如果没有向我们展示更多代码,这可能更符合您的要求。

spyOn(scope, 'onAdmin')and.callFake(done)

【讨论】:

  • 我知道这实际上是冲突的。我想解决方案是按照我在 Stefans 回答中的最后一条评论。
  • 有趣的测试方法!我很想知道你用这种方法测试了什么!?但是,是的,我认为这是你得到你想要的东西的唯一方法——我不知道你想要什么。是不是可以在 callFake 方法中简单调用原函数?因为一个对象是通过引用传递的,你实际上调用的是同一个东西。
  • 我确实试过了,但是没有用。它因堆栈错误而出错,因为它在被监视/监视时不断被调用。
【解决方案2】:

当您编写 done() 时,您会立即调用 done 尝试将 done 作为值传入:

spyOn(scope, 'onAdmin').and.callThrough().and.callFake(done)

【讨论】:

  • 有人编辑了我的问题。我在 callFake 中有 function () { done()}。还是不行。
  • 我发现的唯一解决方法如下:在我的函数被监视之前对其进行备份。仅使用我的备份功能调用Fake,然后再完成。虽然看起来有点 hack
  • 是的,看起来更干净。我会选择解决方法,也更容易阅读。但是为什么你仍然需要调用该函数呢?您的测试是否依赖于它被调用?
  • 是的,他们做到了!或者我希望它们是我猜的:) 这些回调是我知道我从服务器返回数据的一些方式,并且在其中分配了一些变量,并希望检查它们而不是伪造它们。
  • 使用假数据进行测试比让服务器运行测试更好,您可以使用量角器进行e2e测试,以测试与真实应用程序的集成是否有效!
【解决方案3】:

我找到了一种解决方法来做到这一点。 Jasmine 有一个名为 addSpyStategy 的方法,您可以在其中添加自定义策略,如 callThrough 或 callFake。它看起来像这样:

jasmine.addSpyStrategy('callThroughAndThen', (spy, fn) => {
  return function() {
    spy.and.callThrough();
    setTimeout(() => fn(...arguments), 0);
  }
});

超时确保真正的函数在执行自定义函数之前完成。那么对于你的间谍,你可以这样做:

const spy = spyOn(scope, 'onAdmin')
 spy.and.callThroughAndThen(spy, () => {
  // your custom callback
  done();
});

注意:确保将自定义策略放在 beforeEach 块中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 2020-03-22
    • 2019-06-30
    • 1970-01-01
    • 2017-10-05
    • 2018-02-07
    • 2023-03-20
    相关资源
    最近更新 更多