Replace constructors with constructors #193
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Since starting the library, when you've done
td.object(SomeConstructorFunction)
or usedtd.replace
to replace a constructor, td.js has returned a function bag to the test of the instance methods on the constructor. This PR reverses course, and instead returns a fake constructor instead. It's also the first breaking change to the API since we went 1.0, so releasing this will require a major version bump.Benefits to you, dear reader:
prototype
) is now possible (Unable to stub static method on ES6 classes #164)thenDo
andthenThrow
might be handy)td.verify
is now possible, in case you want to ensure the item was instantiated just-so (Make theconstructor
property of td.replaced() instantiable types useful #121)td.replace
API as an implementation detail, that will no longer be necessary, as anyone will be able to fake a constructor withtd.object(SomeConstructorFunction)
(td.constructor() feature for creating fake constructors #54)td.replace
function that deeply replaces nested function properties on whatever we're replacing, since there will no longer be an impedance mismatch (i.e. we won't be returning an object where the subject receives a constructor) (Classes with overridden methods not doubling properly since 1.10.0 #159)instanceof
checks against the original constructor type (Pass instanceof checks for constructor replacement #108)Stuff to-be-done:
td.object(SomeConstructorFunction)
will return a fake constructor which inherits from it, and for which all its functions are replaced by test double functionsSomeConstructorFunction.create()
)prototype
constructor
which should be a reference to the fake constructor itselftoString
which will tell you it's a"test double constructor"
Function.prototype
andObject.prototype
(likevalueOf
,hasOwnProperty
)td.replace('../some/constructor/exporting/module')
will now replace both the actual module with these (new and improved!) fake constructors and return the same fake constructor to the testRequired style changes
This means you'll have to sprinkle a
prototype
onto any existing stubbings in your test code base of constructor-replaced functions. For example:Conclusion
To be honest, for my own practice 1.x worked better, but it was less obvious and it required me to contort the codebase into knots to facilitate other people's styles, like support for static methods. Whichever style you prefer, I apologize for not having the foresight to have implemented this API in the first place.
Because I understand some people have a lot of existing tests and (as tests are untested), they'll be wary of transitioning them, I plan on maintaining a 1.x-specific release branch with the objective of backporting critical bugfixes.
Fixes #166