diff --git a/package.json b/package.json index 5329e8b..5f61398 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ts-sinon", - "version": "2.0.1", + "version": "2.0.2", "description": "sinon library extension to stub whole object and interfaces", "author": { "name": "Tomasz Tarnowski", @@ -53,4 +53,4 @@ "ts-node": "^9.0.0", "typescript": "^4.0.2" } -} +} \ No newline at end of file diff --git a/src/index.spec.ts b/src/index.spec.ts index 92b1a3b..d1ff647 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -282,5 +282,41 @@ describe('ts-sinon', () => { expect(stub.method2(222)).to.equal(expectedNewMethod2Value); expect(stub.method2).to.have.been.calledWith(222); }); + + it('stubs all object methods with inheritance', () => { + class B { + methodB(): string { + return 'B'; + } + } + class A extends B{ + method1(): string { + return 'value1'; + } + method2(x: number): number { + return 13; + } + } + const expectedNewMethod1Value = 'new value'; + const expectedNewMethod2Value = 43; + const expectedMethodBValue = 'new B value'; + const expectedMethod2Argument = 111; + + const stub = stubConstructor(A); + + expect(stub.method1()).to.be.undefined; + expect(stub.method2(expectedMethod2Argument)).to.be.undefined; + expect(stub.methodB()).to.be.undefined; + + stub.method1.returns(expectedNewMethod1Value); + stub.method2.returns(expectedNewMethod2Value); + stub.methodB.returns(expectedMethodBValue); + expect(stub.method2).to.have.been.calledWith(expectedMethod2Argument); + + expect(stub.method1()).to.equal(expectedNewMethod1Value); + expect(stub.method2(222)).to.equal(expectedNewMethod2Value); + expect(stub.methodB()).to.equal(expectedMethodBValue); + expect(stub.method2).to.have.been.calledWith(222); + }); }); }); \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index f8fa312..451f3e5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,7 +15,7 @@ export type ObjectMethodsMap = { export function stubObject(object: T, methods?: ObjectMethodsKeys | ObjectMethodsMap): StubbedInstance { const stubObject = Object.assign(> {}, object); - const objectMethods = Object.getOwnPropertyNames(Object.getPrototypeOf(object)); + const objectMethods = getObjectMethods(object) const excludedMethods: string[] = [ '__defineGetter__', '__defineSetter__', 'hasOwnProperty', '__lookupGetter__', '__lookupSetter__', 'propertyIsEnumerable', @@ -75,6 +75,20 @@ export function stubInterface(methods: ObjectMethodsMap = { }) } +function getObjectMethods(object: object): Array { + const methods: Array = []; + while ((object = Reflect.getPrototypeOf(object))) { + const keys = Reflect.ownKeys(object); + keys.forEach((key) => { + if (typeof key === 'string') { + methods.push(key); + } + }); + } + + return methods; +} + sinon['stubObject'] = stubObject; sinon['stubInterface'] = stubInterface;