我如何testing我的asynchronous茉莉/ nodejs /诺言代码使用间谍
我有一个名为process-promise的模块(例子被简化了),它有一个单独的function,将一个Promise作为input并对其进行处理 – 它还使用外部模块调用其他function,如下所示:
//<process-promise.js> let User = require('user-module'); let processPromise = (promiseObj) => { let user = new User(); promiseObj.then((full_name) => { const [ fname, sname ] = full_name.split(' '); if (fname && sname) { user.setDetails(fname, sname); } else{ console.log('nothing happened'); } }).catch((err) => { console.log(err.message); }); }; module.exports = { processPromise };
我正在尝试使用Jasmine,Rewire和Jasmine spies按照以下代码对上述函数进行unit testing
let rewire = require('rewire'); let mod = rewire('process-promise'); describe('process-promise module', () => { beforeEach(() => { this.fakeUser = createSpyObj('fake-user', ['setDetails']); this.fakeUserMod = jasmine.createSpy('fake-user-mod'); this.fakeUserMod.and.returnValue(this.fakeUser) this.revert = mod.__set__({ User: this.fakeUserMod }); }); afterEach(() => { this.revert(); }); it('fakeUser.setDetails should be called', (done) => { mod.processPromise(Promise.resolve('user name')); done(); expect(this.fakeUser.setDetails).toHaveBeenCalledWith('user','name'); }); });
我期望间谍this.fakeUser.setDetails应该被调用,但我从Jasmine得到的消息“期待间谍fake-user.setAll已被调用['用户','名称'],但它从来没有被调用。 – 问题似乎是承诺是asynchronous的事实,但我已经包括完成function,因为其他SO问题已经build议,但这似乎并不能解决问题。 我的代码有什么问题? 大多数其他SO问题与angular度有关,所以不能帮助解决我的问题。
你在正确的轨道上,诺言是asynchronous的,然后在你的testingdone
function被调用之前,诺言parsing为一个值。 done
函数被用作callback来告诉testing引擎,所有的asynchronous代码已经完成。 在承诺解决了价值 (或者失败)之后应该被调用。
为了做到这一点,您需要对代码进行以下调整:
//<process-promise.js> let User = require('user-module'); let processPromise = (promiseObj) => { let user = new User(); // return a promise, to allow a client to chain a .then call return promiseObj.then((full_name) => { const [ fname, sname ] = full_name.split(' '); if (fname && sname) { user.setDetails(fname, sname); } else{ console.log('nothing happened'); } }).catch((err) => { console.log(err.message); }); }; module.exports = { processPromise };
testing将如下所示:
it('fakeUser.setAll should be called', (done) => { mod.processPromise(Promise.resolve('user name')).then(() => { expect(this.fakeUser.setAll).toHaveBeenCalledWith('user','name'); done(); }).catch(done); });
一定要添加.catch(done)
。 如果承诺解决了错误,这将确保您的testing失败。
可能的是,在你的testing代码执行的时候, promise并没有传播到被测代码中 。 简单的调用done()
并不是同步的魔法。
我不熟悉rewire,所以我将使用proxyquire来分享一个例子
const proxyquire = require('proxyquire'); describe('process-promise module', () => { const fakeUser = { setDetails: jasmine.createSpy('setDetails') }; const fakeUserMod = jasmine.createSpy('fake-user-mod').and.returnValue(fakeUser); const promiseObj = Promise.resolve('user name'); beforeEach((done) => { const processPromiseMod = proxyquire('process-promise', { 'user-module': fakeUserMod, }); processPromiseMod.processPromise(promiseObj); promiseObj.then(() => done()); }); it('fakeUser.setDetails should be called', () => { expect(fakeUser.setDetails).toHaveBeenCalledWith('user','name'); }); });
另请注意, fakeUser
实例中不存在setAll
。 我想你的意思是setDetails
而不是setAll
。
- 如何模拟来自http.request(nodejs,jasmine,sinon)的响应
- 在Karma的跑步者中包含Jasmine-node文件
- 停止JavaScript执行,直到承诺解决
- 使用rewiretesting节点ES6模块 – function未定义
- Jasmine Nodetestingsubprocess
- 即使抛出错误,Jasmine toThrow也不起作用
- 使用茉莉节点来testingmeteor应用程序与自动testing
- 用Jasmine / NodetestingAngular:未捕获types错误“不能设置'mock'的属性undefined
- 使用jasmine和node.jstestingweb API