我有一个名为process-promise的模块(示例已简化),它有一个函数,它将Promise作为输入并对其进行处理 - 它还使用其外部的模块调用其他函数,如下所示:
//<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间谍对上述功能进行单元测试
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');
});
});
我希望Spy this.fakeUser.setDetails应该被调用,但是我从Jasmine那里得到消息“预期spy fake-user.setAll用['user','name'调用]但它从未被调用过“。 - 问题似乎是承诺是异步的事实,但我已经包括完成功能,因为其他SO问题已经建议,但这似乎并没有解决我的问题。我的代码有什么问题?大多数其他SO问题与角度有关,所以对我的问题没有帮助。
答案 0 :(得分:1)
您走在正确的轨道上,承诺是异步的,然后在承诺解析为值之前调用您的测试中的done
函数。 //<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
};
函数用作回调告诉测试引擎,所有异步代码都已完成。它应该在承诺解析为值之后调用(或者在此情况下失败)。
为此,您需要对代码进行以下调整:
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)
请务必添加RecyclerView
。这将确保您的测试失败,以防承诺解决错误。
答案 1 :(得分:0)
在您的测试代码执行时,很可能承诺未传播到测试中的代码。简单地调用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');
});
});
另请注意,setAll
实例中不存在fakeUser
。我猜你的意思是setDetails
而不是setAll
。