sinonjs / sinon

Test spies, stubs and mocks for JavaScript.

Home Page:https://sinonjs.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support callable instances

bojavou opened this issue · comments

Is your feature request related to a problem? Please describe.

A constructor returning a function doesn't work through spies or stubs. This is nonstandard but legitimate in the language. A fake object is constructed instead, which prevents testing callable instances.

> function CallableInstance () { return () => {} }
undefined
> CallableInstance()
[Function (anonymous)]
> new CallableInstance()
[Function (anonymous)]
> const SpiedCallableInstance = sinon.spy(CallableInstance)
undefined
> SpiedCallableInstance()
[Function (anonymous)]
> new SpiedCallableInstance()
CallableInstance {}

Describe the solution you'd like

Function doubles that pass through a function returned at construct time.

My system needs callable instances and I'd like to test them. The problem scenario is a function that instantiates then calls the instance. I'd like to inject a stub as a callable instance double to test that it's used correctly.

import Callable from './callable.js'

export default function useCallable (a, b, c) {
  const callable = new Callable()
  return callable(a, b, c)
}
const callableDouble = sinon.stub()
const CallableDouble = sinon.stub().returns(callableDouble)
inercept('./callable.js', CallableDouble)
useCallable(1, 2, 3)
sinon.assert.calledOnce(callableDouble)
sinon.assert.calledWith(callableDouble, 1, 2, 3)