using sinon.注意两个方法名称相同但参数不同的情况



我试图在一个对象上使用sinon.spy()与两个方法称为draw(都具有相同的名称,但不同的参数),如下所示:

const spy = sinon.spy(obj,'draw')

当我尝试用expect(spy.calledOnceWith(expectedArgument)).toBeTruthy()测试spy时,其中expecteargument与draw的一个函数定义给定的类型匹配,我得到一个错误,说参数不能赋值给draw的另一个函数声明指定的类型。在这种情况下,是否有一种方法可以指定我在创建spy时引用的函数头/声明,以便参数匹配?

YES,您需要对sinon间谍执行双断言,以避免typescript lint错误。这个lint错误是因为sinon spy自动应用已知的最后一个定义。您需要提供将在测试中使用的正确断言。

例如我在Add .ts文件中有一个Add类。如果两个输入都是数字,则处理方法将尝试将它们相加。如果两个输入都是字符串,那么process方法将尝试连接这两个字符串。其他的会产生TypeError。

class Add {
process(a: number, b: number): number;
process(a: string, b: string): string;
process(a: any, b: any):number|string|Error {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
} else if (typeof a === 'string' && typeof b === 'string') {
return `${a}${b}`;
}
throw new TypeError('Incorrect type to process');
}
}
export default Add;

我有一个测试文件:add.spec.ts,它将测试所有的条件。

import sinon from 'sinon';
import { expect } from 'chai';
import Add from '../src/add';
describe('Add', () => {
afterEach(() => {
sinon.restore();
});
it('should process number', () => {
const obj = new Add();
const a = 1;
const b = 2;
// Sinon spy automatically try to apply the last definition known, which is:
// sinon.SinonSpy<[a: string, b: string], string>
// So we need to do type assertions to:
// sinon.SinonSpy<[a: number, b: number], number>
const spy = sinon.spy(obj, 'process') as unknown as sinon.SinonSpy<[a: number, b: number], number>;
const result = obj.process(a, b);
expect(result).to.equal(a + b);
// This line: linter will not complain.
expect(spy.calledOnceWith(a, b)).to.equal(true);
});
it('should process string', () => {
const obj = new Add();
const a = '1';
const b = '2';
// Sinon spy has automatically apply the correct definition.
const spy = sinon.spy(obj, 'process'); // as unknown as sinon.SinonSpy<[a: string, b: string], string>;
const result = obj.process(a, b);
expect(result).to.equal(`${a}${b}`);
// This line: linter will not complain.
expect(spy.calledOnceWith(a, b)).to.equal(true);
});
it('should throw error for invalid type', () => {
const obj = new Add();
const a = 1;
const b = '2';
// Sinon spy automatically try to apply the last definition known, which is:
// sinon.SinonSpy<[a: string, b: string], string>
// So we need to do type assertions to:
// sinon.SinonSpy<[a: any, b: any], Error>
const spy = sinon.spy(obj, 'process') as unknown as sinon.SinonSpy<[a: any, b: any], Error>;
// We also need to cast obj as any, or there will be lint error:
// The call would have succeeded against this implementation,
// but implementation signatures of overloads are not externally visible.
expect(() => (obj as any).process(a, b)).to.throw(TypeError);
// This line: linter will not complain.
expect(spy.calledOnceWith(a, b)).to.equal(true);
});
});

当我在终端使用ts-mocha呼叫跑步者并使用nyc进行报道时,我得到:(我的编辑也没有抗议)。

$ npx nyc ts-mocha test/add.spec.ts 

Add
✓ should process number
✓ should process string
✓ should throw error for invalid type

3 passing (5ms)
----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
add.ts   |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

参考:https://www.typescriptlang.org/docs/handbook/2/everyday-types.html type-assertions

相关内容

最新更新