3 ms·
a) Most code in the wild doesn't have an explicit output and instead is orchestration code. b) Even if you have an output, it's dependent on more complex input
by inertiatic 6y ago
a) Most code in the wild doesn't have an explicit output and instead is orchestration code.
b) Even if you have an output, it's dependent on more complex input of arbitrary types.
Assume that there's a method that returns an input based on summing the output of a method call of it's abstract dependencies.
To do dogmatically correct unit testing you'd pass those 2 mocked dependencies, and have those methods return the values when the right method is called on them.
Then you'd assert that B was called on A, that D was called on C, and that the method under test returns the sum of those returns.
As soon as you move into passing implementations of those 2 dependencies, to anyone dogmatic you're doing integration testing.
Even if the tester isn't being dogmatic, in a lot of cases these inputs are complex enough that building enough actual inputs that are consistent and realistic to cover all the cases is prohibitively costly, so they opt for mocks.
Now, suddenly you just have more code to maintain when making changes, but you feel good about yourself.
- kingdomcome50 6y agoThe interface on our object (O) that you are describing is: O -> int Your unit test is concerned with narrowing the interface above to: O -> int // of specific value based on dependencies If Os only dependencies are A and C, this can be rewritten to: A -> C -> int // of specific value Of course if we assume both A and C, themselves, have dependencies we can recursively rewrite the above until we have a very long interface, but instead you have opted to mock (M) them: M(A) -> M(C) -> int // of specific value You then take it a step further and mock the method calls on each to return a specific value: M(A) -> int M(B) -> int becomes: M(A) -> 3 M(B) -> 5 Okay. Now we can rewrite our interface to: 3 -> 5 -> int // of specific number and our test to: 3 -> 5 -> 8 and make our assertion that the result is indeed the sum of the inputs (not to mention the ridiculous assertions that specific methods were called within the implementation). Yikes... No wonder OOP gets a bad wrap. All that for what amounts to a `sum` function. The designer of the above monstrosity could learn a lot from the phrase "imperative shell, functional core". It sounds like dogma until you are knee deep in trying to test the middle of a large object graph!