我如何检查方法this.athena.startQueryExecution(param)在使用sinon的单元测试中以正确的参数被调用?可能吗?
我有一个简单的代码,可对数据库运行查询:
export class QueryService {
private readonly athena: Athena = new Athena();
constructor() {
}
public async query(date?: Date) {
const param = {
QueryString: this.generateQuery(date),
};
await this.athena.startQueryExecution(param)
.promise();
}
private generateQuery(date?: Date): string {
if (date) {
return `SELECT * FROM TABLE
WHERE date='$date'
} else {
return `SELECT * FROM TABLE
WHERE date='any date'
}
}
我的测试:
describe('QueryService', () => {
let queryService = new QueryService();
describe('Query', () => {
it('test', async () => {
// given
const date: Date = {date: "2019-01-01"};
// where
queryService.query(date);
// then
});
});
});
单元测试解决方案:
queryService.ts
:
import { Athena } from './athena';
export class QueryService {
private readonly athena: Athena = new Athena();
constructor() {}
public async query(date?: Date) {
const param = {
QueryString: this.generateQuery(date),
};
return this.athena.startQueryExecution(param).promise();
}
private generateQuery(date?: Date): string {
if (date) {
return `SELECT * FROM TABLE WHERE date='$date'`;
} else {
return `SELECT * FROM TABLE WHERE date='any date'`;
}
}
}
athena.ts
:
export class Athena {
public startQueryExecution(param) {
return this;
}
public async promise() {
return 'real data';
}
}
queryService.test.ts
:
import { QueryService } from './queryService';
import { Athena } from './athena';
import sinon from 'sinon';
describe('60997196', () => {
afterEach(() => {
sinon.restore();
});
it('should pass', async () => {
const startQueryExecutionStub = sinon.stub(Athena.prototype, 'startQueryExecution').returnsThis();
const promiseStub = sinon.stub(Athena.prototype, 'promise').resolves('fake data');
const queryService = new QueryService();
const date: Date = new Date('2019-01-01');
const actual = await queryService.query(date);
sinon.assert.match(actual, 'fake data');
sinon.assert.calledWithExactly(startQueryExecutionStub, {
QueryString: `SELECT * FROM TABLE WHERE date='$date'`,
});
sinon.assert.calledOnce(promiseStub);
});
});
带有覆盖率报告的单元测试结果:
60997196
✓ should pass
1 passing (29ms)
-----------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------|---------|----------|---------|---------|-------------------
All files | 72.73 | 50 | 60 | 72.73 |
athena.ts | 33.33 | 100 | 0 | 33.33 | 3,6
queryService.ts | 87.5 | 50 | 100 | 87.5 | 18
-----------------|---------|----------|---------|---------|-------------------
源代码:https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/60997196