Sinon - 间谍未被调用但测试进入函数
Sinon - spy not being called but test enters into the function
我用两个存根对函数进行了测试,实际上存根在工作,如果我 console.log res.json 或函数的任何部分中的下一个它会显示内部的间谍对象。无论如何,间谍没有被调用,当我做出断言时它说 "expected spy to have been called at least once but was never called"。该程序有效,但测试很疯狂。请帮助我!
我有这样的功能:
export function createOrUpdateToken(req, res, next) {
const { code, redirect_uri, realm_id, quickbooksAuth } = req.body;
if (!code || !redirect_uri || !realm_id) {
const message = 'Authorization code, Redirect URI and Realm Id are required';
return next(new CustomError('Bad Request', message, 400));
}
return issueRefreshTokenBasedOnAuthorizationCode(
{
redirect_uri,
authorizationCode: code,
authorization: quickbooksAuth,
})
.then((response) => {
const { body: { refresh_token } } = response;
return securityModel.findOneAndUpdate(
{ realmId: realm_id },
{ refreshToken: refresh_token },
{ upsert: true },
(err) => {
if (err) return next(err);
return res.json('Authentication successfull');
});
})
.catch((err) => {
return next(err);
});
}
测试是这样的:
it('Should create or update token', () => {
req.body = {
code: '1234',
redirect_uri: 'www.test.com',
realm_id: '12345',
quickbooksAuth: 'dhajksdas.dsajdosaiudjsa.dsaojpdas'
};
sinon
.stub(intuit, 'issueRefreshTokenBasedOnAuthorizationCode')
.resolves({
body: {
refresh_token: 'hjdklasdashda.dsa.dasdsa.dasddasdas'
}
});
sinon
.stub(securityModel, 'findOneAndUpdate')
.withArgs({ realmId: req.body.realm_id },
{ refreshToken: 'hjdklasdashda.dsa.dasdsa.dasddasdas' })
.yields(null);
createOrUpdateToken(req, res, next);
sinon.assert.called(res.json);
});
条件是:
beforeEach(() => {
res = {
json: sinon.spy()
};
next = sinon.spy();
});
afterEach(() => {
sinon.restore();
})
问题
createOrUpdateToken
执行一些异步代码,这些代码在 returns 和 sinon.assert.called(res.json)
运行并失败时尚未完成。
解决方案
您已经从 createOrUpdateToken
返回一个 Promise,因此只需将您的测试设为 async
测试,并在 运行 断言之前 await
Promise:
it('Should create or update token', async () => { // make the test function async
req.body = {
code: '1234',
redirect_uri: 'www.test.com',
realm_id: '12345',
quickbooksAuth: 'dhajksdas.dsajdosaiudjsa.dsaojpdas'
};
sinon
.stub(intuit, 'issueRefreshTokenBasedOnAuthorizationCode')
.resolves({
body: {
refresh_token: 'hjdklasdashda.dsa.dasdsa.dasddasdas'
}
});
sinon
.stub(securityModel, 'findOneAndUpdate')
.withArgs({ realmId: req.body.realm_id },
{ refreshToken: 'hjdklasdashda.dsa.dasdsa.dasddasdas' })
.yields(null);
await createOrUpdateToken(req, res, next); // await the returned Promise
sinon.assert.called(res.json); // SUCCESS
});
我用两个存根对函数进行了测试,实际上存根在工作,如果我 console.log res.json 或函数的任何部分中的下一个它会显示内部的间谍对象。无论如何,间谍没有被调用,当我做出断言时它说 "expected spy to have been called at least once but was never called"。该程序有效,但测试很疯狂。请帮助我!
我有这样的功能:
export function createOrUpdateToken(req, res, next) {
const { code, redirect_uri, realm_id, quickbooksAuth } = req.body;
if (!code || !redirect_uri || !realm_id) {
const message = 'Authorization code, Redirect URI and Realm Id are required';
return next(new CustomError('Bad Request', message, 400));
}
return issueRefreshTokenBasedOnAuthorizationCode(
{
redirect_uri,
authorizationCode: code,
authorization: quickbooksAuth,
})
.then((response) => {
const { body: { refresh_token } } = response;
return securityModel.findOneAndUpdate(
{ realmId: realm_id },
{ refreshToken: refresh_token },
{ upsert: true },
(err) => {
if (err) return next(err);
return res.json('Authentication successfull');
});
})
.catch((err) => {
return next(err);
});
}
测试是这样的:
it('Should create or update token', () => {
req.body = {
code: '1234',
redirect_uri: 'www.test.com',
realm_id: '12345',
quickbooksAuth: 'dhajksdas.dsajdosaiudjsa.dsaojpdas'
};
sinon
.stub(intuit, 'issueRefreshTokenBasedOnAuthorizationCode')
.resolves({
body: {
refresh_token: 'hjdklasdashda.dsa.dasdsa.dasddasdas'
}
});
sinon
.stub(securityModel, 'findOneAndUpdate')
.withArgs({ realmId: req.body.realm_id },
{ refreshToken: 'hjdklasdashda.dsa.dasdsa.dasddasdas' })
.yields(null);
createOrUpdateToken(req, res, next);
sinon.assert.called(res.json);
});
条件是:
beforeEach(() => {
res = {
json: sinon.spy()
};
next = sinon.spy();
});
afterEach(() => {
sinon.restore();
})
问题
createOrUpdateToken
执行一些异步代码,这些代码在 returns 和 sinon.assert.called(res.json)
运行并失败时尚未完成。
解决方案
您已经从 createOrUpdateToken
返回一个 Promise,因此只需将您的测试设为 async
测试,并在 运行 断言之前 await
Promise:
it('Should create or update token', async () => { // make the test function async
req.body = {
code: '1234',
redirect_uri: 'www.test.com',
realm_id: '12345',
quickbooksAuth: 'dhajksdas.dsajdosaiudjsa.dsaojpdas'
};
sinon
.stub(intuit, 'issueRefreshTokenBasedOnAuthorizationCode')
.resolves({
body: {
refresh_token: 'hjdklasdashda.dsa.dasdsa.dasddasdas'
}
});
sinon
.stub(securityModel, 'findOneAndUpdate')
.withArgs({ realmId: req.body.realm_id },
{ refreshToken: 'hjdklasdashda.dsa.dasdsa.dasddasdas' })
.yields(null);
await createOrUpdateToken(req, res, next); // await the returned Promise
sinon.assert.called(res.json); // SUCCESS
});