Kind of, but three big problems in practice are:
- runtime state you need to initialize if your code is written in a stateful manner
- other methods/functions in different modules/classes the code you want to test calls out to
- the fact that method/function and module/class separation is (and IMO always should be) primarily driven by needs of production architecture, not testing, means that it may not be perfect for testing needs
Add to that the failure of testing tools and methodologies (like "don't test private methods" meeting "separate out duplicated or complex code into private methods"), and I feel the problems are real.
----
Here's an idea that just popped into my head right now: how about "hash-based testing"? You take a code you want to test, like:
private Integer foo(String bar, Frobnicator quux) {
String frob = quux.invokeMagic(bar);
return memberApi.transform(frob);
}
and turn it into:
Method cut = 3);
}>>;
//continue testing cut()
The idea being, the compiler or whatever external tooling ensures that the original method in production code, and the inline-modified method in tests, are the same with respect to some equality/hashing function that always treats expressions "foo" and "MOCK(foo) AS(bar)" as equal.
This way, you end up being able to mock everything precisely, inline, in whatever way you see fit, with your tooling ensuring that the actual code stays in sync with the test, since whenever the original method changes in any meaningful way, you'll fail the code "equality" test.
Might be a stupid idea, I welcome comments.
(INB4 testing to implementation instead of the interface - if you have to mock anything, you're already testing to implementation, and this way you can inject testing alterations precisely, instead of having to turn your architecture inside-out to support IoC/DI/whatever the current testing-enabling OOP fad is.)