It baffles me that the original comments for the article express so much agreement. "Exhibit A" doesn't have anything to do with mocking.
In "Exhibit B" he tries to test operations on values with mocks, which is never a good idea. Ironically, the multiplication example at the bottom shows how constructed his example is. Of course I've seen people in the "mocking world" who write code like this, but that's not an argument against mocking.
I think "Exhibit C" is actually valid, but his solution requires a self written AOP framework and the test still relies on implementation details.
"Compose two functions, and you still have a function. Compose ten, or a hundred, and it is still a function mapping values to values."
The problem being that when you compose two functions the number of possible input combinations to function 1 multiplied by the number of possible input combinations to function 2.
When you have 10 functions, each with two inputs, combining them gives you 2^10 combination to test - 1024 combinations.
Whereas if you test each one separately you can test 20 combinations, and get the same coverage.
I don’t know what you’re talking about, but it isn’t function composition. Function composition consumes outputs as it produces inputs, in equal measure — in f(g(x)), the domain of f is bounded by the codomain of g, which is itself bounded by x. If g has three branches, but f always outputs a value that takes the first branch, then g will only ever follow one branch in your test; you won’t get a combinatoric explosion of possible branches taken.
You might be thinking more of testing several expressions independently, e.g. assert([f(x), g(x)] == […]). This does what you’re talking about, but I don’t think anybody (including the author of the post) was recommending this.