模拟传入客户端的函数的req和res的最佳方法是什么,例如下面的redis-get函数



因此,我试图找出模拟函数请求和响应的最佳方法,我看到了许多方法,有些使用jest.fn(),有些使用sinon,还有一些使用外部包。

当想要返回状态、json以及请求的内容时,最好的方法是什么?请参阅下面的代码。

export const redisGet = (client) => async (req, res, next) => {
try {
const {
postCode,
houseNumber,
} = req.params

const addressObj = {
postCode,
houseNumber,
}

const addressGetParams = JSON.stringify(addressObj)
await client.get(addressGetParams, (err, data) => {
if (data) {
return res.status(200).send({
error: false,
message: `Addresses found.`,
data: JSON.parse(data)
})
}

if (err) {
return res.status(400).send({
error: err,
message: `Bad request`,
data: JSON.parse(data),
})
}
next()
})
} catch (e) {
throw Error(e)
}
}

jestjssinonjs都可以模拟/存根模块。选择其中一个就足够了。下面是一个使用jestjs的示例。单元测试解决方案:

index.ts:

export const redisGet = (client) => async (req, res, next) => {
try {
const { postCode, houseNumber } = req.params;
const addressObj = { postCode, houseNumber };
const addressGetParams = JSON.stringify(addressObj);
client.get(addressGetParams, (err, data) => {
if (data) {
return res.status(200).send({
error: false,
message: `Addresses found.`,
data: JSON.parse(data),
});
}
if (err) {
return res.status(400).send({
error: err,
message: `Bad request`,
});
}
next();
});
} catch (e) {
throw Error(e);
}
};

index.test.ts:

import { redisGet } from './';
describe('63253476', () => {
it('should found addresses', async () => {
const mClient = {
get: jest.fn().mockImplementationOnce((params, callback) => {
callback(null, '{"id": 1}');
}),
};
const mReq = { params: { postCode: 123, houseNumber: 456 } };
const mRes = { status: jest.fn().mockReturnThis(), send: jest.fn() };
const mNext = jest.fn();
await redisGet(mClient)(mReq, mRes, mNext);
expect(mClient.get).toBeCalledWith(JSON.stringify({ postCode: 123, houseNumber: 456 }), expect.any(Function));
expect(mRes.status).toBeCalledWith(200);
expect(mRes.send).toBeCalledWith({ error: false, message: `Addresses found.`, data: { id: 1 } });
expect(mNext).not.toBeCalled();
});
it('should handle error', async () => {
const mErr = new Error('timeout');
const mClient = {
get: jest.fn().mockImplementationOnce((params, callback) => {
callback(mErr);
}),
};
const mReq = { params: { postCode: 123, houseNumber: 456 } };
const mRes = { status: jest.fn().mockReturnThis(), send: jest.fn() };
const mNext = jest.fn();
await redisGet(mClient)(mReq, mRes, mNext);
expect(mClient.get).toBeCalledWith(JSON.stringify({ postCode: 123, houseNumber: 456 }), expect.any(Function));
expect(mRes.status).toBeCalledWith(400);
expect(mRes.send).toBeCalledWith({ error: mErr, message: `Bad request` });
expect(mNext).not.toBeCalled();
});
it('should do nothing and call next middleware', async () => {
const mClient = {
get: jest.fn().mockImplementationOnce((params, callback) => {
callback();
}),
};
const mReq = { params: { postCode: 123, houseNumber: 456 } };
const mRes = { status: jest.fn().mockReturnThis(), send: jest.fn() };
const mNext = jest.fn();
await redisGet(mClient)(mReq, mRes, mNext);
expect(mClient.get).toBeCalledWith(JSON.stringify({ postCode: 123, houseNumber: 456 }), expect.any(Function));
expect(mRes.status).not.toBeCalled();
expect(mRes.send).not.toBeCalled();
expect(mNext).toBeCalled();
});
});

带覆盖率报告的单元测试结果:

PASS  src/stackoverflow/63253476/index.test.ts (11.338s)
63253476
✓ should found addresses (8ms)
✓ should handle error (2ms)
✓ should do nothing and call next middleware (2ms)
----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |    92.86 |      100 |      100 |    91.67 |                   |
index.ts |    92.86 |      100 |      100 |    91.67 |                26 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        13.824s

相关内容

  • 没有找到相关文章

最新更新