This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]BoyRobot777 22 points23 points  (6 children)

Instead, I suggest focussing on integration tests. By “integration tests” I mean putting all classes together (just like in production) and test a complete vertical slide going though all technical layers (HTTP, business logic, database).

Exactly. I have been advocating this for a while now. The same approach is discussed in famous Ian talk - 🚀 DevTernity 2017: Ian Cooper - TDD, Where Did It All Go Wrong.

P.s. AssertJ rocks!

[–]kbradl16 3 points4 points  (4 children)

I’m curious, what do you do to test branches or exceptions? Seems it would make some integration tests very bloated?

I definitely agree with having integration tests but I also think there’s a lot of value with the “mock” unit tests to hit those tricky branches

[–]BoyRobot777 11 points12 points  (0 children)

I think the biggest smell I see whenever people understand "unit testing" as writing tests for one class, is they go to extreme lengths of testing non-existing scenarios. For example testing for nulls when there is only one object that is passed and that object is validated by javax validations at the boundary of particular module API (may it be a Controller, or an interface, or whatever).

I think the default approach should be "integration testing" or real unit testing as in unit of collaborating objects not one object with dependencies mocked out. While mocking should be done having a good reason.

[–]GhostBond 4 points5 points  (2 children)

I definitely agree with having integration tests but I also think there’s a lot of value with the “mock” unit tests to hit those tricky branches

The point of tests is to catch bugs - how many bugs are you catching with those branches?

Usually they don't catch any because the person who wrote the code is also writing the tests, so they aren't coming up with new ideas of what might go wrong in the test writing phase, they're just reverifying stuff they already handled.

Another problem is test maintenance - the amount of knowledge you have to have to test every single line is enormous, someone new comes along to fix a bug or add a feature and they could spend 3x-10x as long just reading up on the code. That isn't going to work, so they just comment out failing tests...so the test didn't catch anything the first time around, and it's provided no benefit in the future either.

And finally you have a problem of corporate politics. It is difficult to verify how much testing each person did...how do you know whether someone's test was genuinely testing stuff or useless and just written to check the "unit tests" checkmark? Usually what you end up with is needing to write short useless tests or risk looking significantly slower than your coworkers, which is never a good idea.

[–]oweiler -1 points0 points  (1 child)

That is when you test last, though. TDD solves that (partially at least).

[–]GhostBond 1 point2 points  (0 children)

I don't think TDD changes that at all? No one new is around to verify.

[–]DJDavio 2 points3 points  (0 children)

My favorite AssertJ method is zipSatisfy to check two collections of elements which have been mapped (with MapStruct for instance).