我正在使用TypeScript编写一个利用AWS开发工具包的非常简单的服务。我的Jest单元测试通过了,但是覆盖率报告说'return result.Items'行未覆盖。谁能说出为什么呢?是开玩笑的错误吗?
// service file
/**
* Gets an array of documents.
*/
function list(tableName) {
const params = {
TableName: tableName,
};
return docClient
.scan(params)
.promise()
.then((result) => {
return result.Items;
});
}
// test file
const stubAwsRequestWithFakeArrayReturn = () => {
return {
promise: () => {
return { then: () => ({ Items: 'fake-value' }) };
},
};
};
it(`should call docClient.scan() at least once`, () => {
const mockAwsCall = jest.fn().mockImplementation(stubAwsRequest);
aws.docClient.scan = mockAwsCall;
db.list('fake-table');
expect(mockAwsCall).toBeCalledTimes(1);
});
it(`should call docClient.scan() with the proper params`, () => {
const mockAwsCall = jest.fn().mockImplementation(stubAwsRequest);
aws.docClient.scan = mockAwsCall;
db.list('fake-table');
expect(mockAwsCall).toBeCalledWith({
TableName: 'fake-table',
});
});
it('should return result.Items out of result', async () => {
const mockAwsCall = jest
.fn()
.mockImplementation(stubAwsRequestWithFakeArrayReturn);
aws.docClient.get = mockAwsCall;
const returnValue = await db.get('fake-table', 'fake-id');
expect(returnValue).toEqual({ Items: 'fake-value' });
});
答案 0 :(得分:3)
未涵盖的行是传递给then
的成功回调。
您的模拟将then
替换为不接受任何参数而仅返回一个对象的函数。测试期间,来自代码的回调将传递给then
模拟,但它不会调用该回调,因此Jest
会正确报告该测试未覆盖该回调。
与其尝试返回看起来像Promise
的 的模拟对象,不如从模拟中返回实际解析的Promise
:
const stubAwsRequestWithFakeArrayReturn = () => ({
promise: () => Promise.resolve({ Items: 'fake-value' })
});
...那样,then
仍将是实际的Promise.prototype.then
,您的回调将按预期方式被调用。
您还应该await
返回的Promise
,以确保在测试完成之前已调用了回调:
it(`should call docClient.scan() at least once`, async () => {
const mockAwsCall = jest.fn().mockImplementation(stubAwsRequest);
aws.docClient.scan = mockAwsCall;
await db.list('fake-table'); // await the Promise
expect(mockAwsCall).toBeCalledTimes(1);
});
it(`should call docClient.scan() with the proper params`, async () => {
const mockAwsCall = jest.fn().mockImplementation(stubAwsRequest);
aws.docClient.scan = mockAwsCall;
await db.list('fake-table'); // await the Promise
expect(mockAwsCall).toBeCalledWith({
TableName: 'fake-table',
});
});
答案 1 :(得分:0)
chai-promise的图书馆值得一看。
https://www.chaijs.com/plugins/chai-as-promised/
与其手动将您的期望与承诺达成一致 满足和拒绝的处理程序。
doSomethingAsync().then(
function (result) {
result.should.equal("foo");
done();
},
function (err) {
done(err);
}
);
您可以编写表达您真正含义的代码:
return doSomethingAsync().should.eventually.equal("foo");