Before we start, I am aware of the following: I used a click semi click-baity headline to get you here. I am shamelessly sharing yet another /faking framework ( ) among many existing ones. mocking substitute.js I am the author of that said framework. I am not Facebook or Google, just a developer like you. I’m not even a writer — you must have already guessed that part. So why pay attention and even give me one more minute of your time? Simple. I’m almost certain I can give that minute back to you, and plenty more in the future. I won’t be going into details about what faking or mocking is, or why it’s a good idea. This post assumes you already know that. Table of contents Comparing frameworks with code samples Limitations Getting substitute.js Comparing frameworks with code samples All of the examples below assume that there is a class called and an interface backing it up called . These are defined below respectively. RealCalculator CalculatorInterface With these types defined, let’s get on with it. I hope the examples speak for themselves, and that you’ll agree with the following: That syntax is easier to remember, easier to learn and faster to write. substitute.js That the ability to fake/mock interfaces is a huge advantage over existing frameworks, due to its effect on TDD. Creating a mock of a class ts-mockito With you first create a mock “class” or “constructor”, and you can then create a real non-fake instance from this mock. ts-mockito typemoq The same goes for . typemoq substitute.js For , the instance and the fake is one and the same. substitute.js Creating a mock of an interface Creating a mock from an interface makes a lot easier with a lot less code, all while being able to compile along the way. With interface mocking, you can: TDD Start by defining your interfaces (no implementation). Depend on those interfaces in your code. Write the tests for the interfaces using fakes (you can fake the interfaces without writing the classes first!). Implement the code with real classes. Smile. You were able to have full strong-typing and something that actually compiles all the way through the process. No squiggly lines, just pure pleasant TDD. ts-mockito This is unfortunately not supported. typemoq The same goes for — not supported. typemoq substitute.js In , you can fake from an just fine. The magic behind this is possible due to ES6 proxies. substitute.js interface Stubbing methods In this example we’ll compare how the three frameworks handle stubbing of methods. ts-mockito With you specify the arguments and return values on the mock object within wrapper functions. ts-mockito typemoq The same goes for . typemoq substitute.js For , you can define your return values on the mock itself and yet use it in a fluent and strong typed manner. substitute.js Stubbing properties In this example we’ll compare how the three frameworks handle stubbing of properties. ts-mockito With you specify the return values on the mock object within wrapper functions. ts-mockito typemoq The same goes for . typemoq substitute.js For , you can define your return values on the mock itself and yet use it in a fluent and strong typed manner. substitute.js Throwing errors In this example we’ll compare how the three frameworks handle throwing errors. The same syntax across all frameworks also apply for methods in a similar manner described above, so we won’t go through that. ts-mockito With you specify the exception to throw on the mock object within wrapper functions. ts-mockito typemoq The same goes for . typemoq substitute.js For , you use the function and wrap it in a lambda to throw an error. substitute.js returns Call count verification In this example we’ll compare how the three frameworks handle call count verification. The same syntax across all frameworks also apply for properties, so we won’t go through that. Note that _substitute.js_ does not support the “at least _n_ times” verification nor the “fewer than _n_ times” verification because I personally believe it is bad practise — your tests should always be deterministic. You should always know the amount of calls to expect in a test. ts-mockito With you specify the operation to match on the mock object within wrapper functions. ts-mockito typemoq The same goes for . typemoq substitute.js For , you use the function and call the operation on its return value. substitute.js received Alternatively, you can also use which does exactly what you would expect. didNotReceive Proxying calls Proxying calls can be useful if you want your fake method to do something else. ts-mockito With you specify the operation to match on the mock object within wrapper functions, and then use another function to specify which method to proxy calls to. ts-mockito typemoq The same goes for . typemoq substitute.js For , you use the function and specify which function to proxy calls to. substitute.js mimicks Matching arguments Argument matchers allow you to be more explicit about when you want to fake something, or what calls you expect to receive. ts-mockito With you use functions like and to match arguments. ts-mockito anything between I have not found a way to specify a custom lambda to express a custom matcher yet in _ts-mockito_ — let me know if you know of any in the comments section. typemoq Almost the same as , but supports lambdas. ts-mockito substitute.js Here, the syntax is nice and clear. A nice little detail is that there is strong-typing all the way even as you type, with full type inference (it even knows what type is in the function. x Arg.is Errors produced by call verification Proxying calls can be useful if you want your fake method to do something else. ts-mockito displays the method name and parameters as well as how many times a call was expected, but does not show the total calls that were recorded. ts-mockito The above code throws: Expected “add(strictEqual(1), strictEqual(2))” to be called at least 1 time(s). But has been called 0 time(s). typemoq The same goes for , except it also displays a list of calls recorded typemoq The above code throws: Expected invocation of RealCalculator.add(It.isValue(1),It.isValue(2)) at least 1 times, invoked 0 times Configured setups:RealCalculator.add(It.isValue(1),It.isValue(2)) Performed invocations:RealCalculator.add(3,4) substitute.js For , you use the function and specify which function to proxy calls to. substitute.js mimicks The above code will throw: Expected one or more calls to the method c with arguments [1, 2], but received none of such calls. All calls received to method c: -> 1 call with arguments [3, 4] Limitations The above all looks quite good, right? But there are limitations in like any other framework. substitute.js Below is a list all of the things the other frameworks can do that can’t, and a reason for not supporting it. substitute.js Partial mocks Partial mocks are typically bad if you rely on only a few faked methods. Typically when testing, you want to fake either everything or . almost everything While does not support partial mocks, you can explicitly proxy each method you want to “mimick” from the real instance. substitute.js Call order verification The outside world (using the public interface of your unit) should not care about which order your unit calls its dependencies’ methods. I see this as an anti-pattern, which is why it is not supported. More? Are there more examples that can’t do that the others can? Let me know in the comments, and I’ll add it or justify why it hasn’t been added to the framework. substitute.js tries to make the types of faking operations you use 99% of the times simple, but it should still be flexible enough to cover complex cases, if one is willing to sacrifice the good-looking syntax. substitute.js Getting substitute.js Here’s the command you’ll need to install . Note that it requires 3 or later. substitute.js TypeScript npm install @fluffy-spoon/substitute --save-dev GitHub: https://github.com/ffMathy/FluffySpoon.JavaScript.Testing.Faking NPM: https://www.npmjs.com/package/@fluffy-spoon/substitute