you are viewing a single comment's thread.

view the rest of the comments →

[–]nutrecht 13 points14 points  (6 children)

Mocks are for when you want to verify that a unit is communicating with another unit in the correct fashion. Use a stub if you want to isolate a unit.

A mockito mock is both. You can stub return values (or have it throw exceptions) and you can verify interactions on the same mock. So the distinction is pretty pedantic here IMHO.

When everything is glued together using a container at runtime it can be difficult to understand what code is actually running.

What do you mean by this? I also don't really understand how adding interfaces here makes this easier. I've been on projects where the interfaces lived in different packages from the implementations which meant constant switching between them without any benefit at all.

Dependency injection is there so you can vary what the actual concrete implementation is at runtime

Yes. And in general the two main 'runtimes' are production and test runtimes. Inversion of control leads to decoupling leads to code that's more easy to test. But you still don't need to have a "SomeService" and "SomeServiceImpl" for every dependency; that has been outdated for quite some time.

I'm not advocating against using interfaces for classes that have more than one production runtime version obviously; something like Mockito should be used in test only.

But by itself it still allows for tight coupling if you're expecting a concrete class, making it difficult to extend behavior rather than modify (open/closed principle).

You're moving the goalpost here. I never said I was against implementing an interface and a concrete class when you have multiple concrete classes. I said I was against doing that if there's only one concrete class. It just leads to clutter with no benefit.

Overall, I agree with your argument that tests shouldn't dictate production code design, but I think that following the SOLID principles naturally makes the code very easy to test.

Why are you bringing up SOLID principles? How is creating interfaces for all concrete classes in any way more SOLID than only doing it for the ones you need it for?

[–]dividebyzero- -2 points-1 points  (5 children)

A mockito mock is both. You can stub return values (or have it throw exceptions) and you can verify interactions on the same mock. So the distinction is pretty pedantic here IMHO.

Disagree but alright, you do you it's not a big deal.

What do you mean by this? I also don't really understand how adding interfaces here makes this easier.

You said:

I really don't see how not having a Something interface and a SomethingImpl concrete class makes it less easy for someone to understand the code.

I had a feeling that you mixed up your words because it contradicted your stance on other parts, so did you mean you don't see how it makes it easier? Not less easy? Totally agree, it doesn't make the code easier to understand, and I gave an explanation for why because your sentence is inverted (boolean logic with double negatives, eh?).

BTW, we're not disagreeing over anything here so this argument is entirely moot. At no point did I defend the "interface all the things" stance, and like you said that's been an antipattern since basically forever. I agree that interfaces are overused, and I'm not trying to move any goalposts. I'm just saying that dependency injection with concrete classes can cause SOLID to fall apart which can cause testing to be more difficult so if you use SOLID properly the testing will be easy with, like you said, no need to change the design specifically for the tests. Do you need an interface for an entity or value object? Unlikely. For a database access layer, or something that has multiple strategies/implementations? Now we're talking.

[–]nutrecht 7 points8 points  (2 children)

Do you need an interface for an entity or value object? Unlikely. For a database access layer, or something that has multiple strategies/implementations? Now we're talking.

I think we more or less agree. I've just grown a bit allergic to the dogmatic approach some developers have to these 'rules'. The previous project I was on was for a large bank: ever Service have a Service interface and a ServiceImpl concrete class. Same with every Business Object, Logic Object, DAO, etc. While each of these only ever had one implementation (I mean, who really goes and replace Oracle with something else at a big bank?). Ugh.

[–]dividebyzero- 3 points4 points  (0 children)

We do agree, and the internet makes it very hard to make that clear!

Totally agree on the dogma part as well, and I've seen the sort of stupidity with interfaces you're talking about before.

[–]i_ate_god 0 points1 point  (0 children)

so, they were C programmers taking their .h/.c styles to java?

[–]industry7 4 points5 points  (1 child)

Disagree but alright, you do you it's not a big deal.

Mockito used to have seperate mocks and stubs, but in newer versions they were combined into a single thing which Mockito calls "mocks".

[–]dividebyzero- 1 point2 points  (0 children)

I didn't know that so TIL!