jasmine - 如何监视内部具有 Promise 且不返回结果但处理响应本身的函数?
问题描述
我怎样才能 spyOn 一个名为放置在对象中的方法?
// Game.js
export default {
mine: null,
handle: function(me) {
console.log(" FOOOOO " + me)
},
setSource: function() {
this.mine.getSource().then((response) => {
const {source} = response
this.handle(source)
})
}
}
在这里我尝试窥探:
// GameSpec.js
import Game from '../../lib/jasmine_examples/Game'
Game.mine = {}
describe("Game", function() {
it("should set source and handle it", function() {
Game.mine.getSource = () => {
return new Promise((resolve)=>{
resolve( {
source : 'BAAAAR'
})
})
}
spyOn(Game, 'handle').and.callThrough()
Game.setSource()
expect(Game.handle).toHaveBeenCalled()
});
});
在输出中,您可以看到函数“handle”被调用:
Started
F FOOOOO BAAAAR
Failures:
1) Game should set source and handle it
Message:
Expected spy handle to have been called.
Stack:
Error: Expected spy handle to have been called.
at <Jasmine>
at UserContext.<anonymous> (/Users/silverbook/Sites/zTest/jasmine/spec/jasmine_examples/PlayerSpec.js:20:29)
at <Jasmine>
1 spec, 1 failure
但jasmine
说它没有被调用。
如果我删除了模拟Promise
测试通过,但我需要那里。在另一个测试中,我将在 Promise 中返回一个错误,并让它从另一个函数处理。
所以Promise
打破了测试,但为什么呢?
解决方案
测试同步执行,并且在expect
排队的回调this.mine.getSource().then()
有机会执行之前失败。
对于Jasmine
>= 2.7 和async
函数支持,您可以将测试函数转换为async
函数并添加await Promise.resolve();
要暂停同步测试并让任何排队回调执行的位置。
对于您的测试,它看起来像这样:
import Game from '../../lib/jasmine_examples/Game'
Game.mine = {}
describe("Game", function() {
it("should set source and handle it", async () => {
Game.mine.getSource = () => {
return new Promise((resolve)=>{
resolve( {
source : 'BAAAAR'
})
})
}
spyOn(Game, 'handle').and.callThrough();
Game.setSource();
await Promise.resolve(); // let the event loop cycle
expect(Game.handle).toHaveBeenCalled();
});
});
对于较旧的 (>= 2.0)Jasmine
版本,您可以done()
像这样使用:
import Game from '../../lib/jasmine_examples/Game'
Game.mine = {}
describe("Game", function() {
it("should set source and handle it", (done) => {
Game.mine.getSource = () => {
return new Promise((resolve)=>{
resolve( {
source : 'BAAAAR'
})
})
}
spyOn(Game, 'handle').and.callThrough();
Game.setSource();
Promise.resolve().then(() => {
expect(Game.handle).toHaveBeenCalled();
done();
});
});
});
推荐阅读
- reactjs - 我可以从 CDN 制作 Reason+React 导入反应模块吗?
- postman - 邮递员的回复不干净
- sql - 如何按日期求和
- python - 在 python 中使用 numpy
- excel - 您可以在 VBA 中的拆分项上递归使用拆分功能吗?
- c# - LINQ 查询 - 如何参数化选择不同的查询
- java - 如何在 env->GetStringUTFChars(...) 之后使用 env->ReleaseStringUTFChars(...)
- git - 如何 git 还原通过樱桃采摘完成的合并提交
- python - 重新分配数据框的索引而不添加列
- javascript - 使用 vuex 给定项目更新数据