Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I disagree. I think often times "making things testable" leads to code which is much harder to follow. For instance, dependency injection often leads to things depending on abstract interfaces rather than concrete implementations, and it becomes much harder to trace through code.

I actually think integration tests are vastly more useful than unit tests, and in general unit tests should be employed: a) if you are testing business logic which is not obvious, b) as a method of debugging or c) when it makes it faster to iterate on a particular piece of code during development.

I think excitement about unit-testing has become over-generalized to domains where it doesn't make sense. For instance, in a mobile application unit testing your networking layer does not add value 99% of the time, will be way less helpful than hands-on testing of the UX, and just adds busy work to modifying the code-base because you have to maintain the tests as well.



> depending on abstract interfaces rather than concrete implementations

That's definitely a problem... in Java. I've had to deal with it before (in Java), and I think part of the problem is that people start using that abstraction pattern before there's actually multiple potential concrete implementations. In Ruby, I've applied something like this pattern, except all I'm doing is wrapping the service library to make my own DSL, and it's working tremendously well and allowing for excellent testing.

And yes. Anything can be overapplied / mis-applied, and sure, unit testing might be more susceptible / abused in these ways.

Essentially, I unit-test my functional code (libraries, etc) and I integration test my OO code (actual features, as the whole feature). It's not only a really easy way to test each kind of thing, but enforcing the functional library / OO features has led to (IMO) practically perfect code :D


> people start using that abstraction pattern before there's actually multiple potential concrete implementations

But that's what I mean: the second concrete implementation is the mock which has been created for unit testing, and this is how unit testing introduces complexity and indirection.


Hmm.

So what I'm doing is that I have a wrapper object with a private member variable that's the client from the service's API library (for this example, it's DialogueFlow). My wrapper then has a function for each basic thing that my code actually wants to do with the library, translating from the plain data objects (or straight arguments) that're in use in the rest of my codebase into the nested object mess that DF talks in (and back again, when there's return values).

Then in tests, I just monkeypatch the private `client` method/variable to return/be the mock. The mock then replicates only the functionality that I actually use from the service's library, which is easy to do since there's only one file to look at for all usage.

I now have my own DSL for interacting with the service, and I understand the service well enough to fake it, which has been super helpful. So far I'm loving it, and it doesn't feel at all like the "where's the !#$%! bean" hell of Spring.


This is a place where Go's duck typing really shines. You can create a mock class without having to modify the actual code.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: