Exactly. I don't want to assume gp doesn't understand the difference between unit and integration tests, but I think the only alternative conclusion is they don't think there is value in unit tests. I disagree, and happily inject mock objects for testing.
The problem with unit tests + heavy mocking is that you essentially makes any sort of class reorganisation as a massive pain.
I try for sociable unit tests(it's a thing), which classes that are expected to work together 100% of the time are tested together. Mock out the external dependencies(http etc) or things that are expected to change.
I tend to only mock out/simulate primary ports(inputs, such http requests), and secondary ports(databases calls) for simple web apps.
I may start isolating stuff for testing purposes when it can be used well independently such a piece of middleware, or things that can be used by multiple parts of a project.
The main difference socaiable unit tests, and integration tests is that traditional integration tests still talk to the db.
Part of the problem with unit tests that mock everything is that they are very time consuming to write. Minor changes in how classes interact result in 5x the time needed to update unit tests.
Furthermore, unit tests don't really test product use cases.
Personally, I find testing a single class with mocking best for edge cases, error conditions, or when a class is something like a custom collection that has little outside dependencies.
> Part of the problem with unit tests that mock everything is that they are very time consuming to write. Minor changes in how classes interact result in 5x the time needed to update unit tests.
Unit tests are supposed to verify a software unit's design contract. If a minor change breaks your design contract then either the change is not minor at all or you have more serious problems to deal with than writing unit tests.
While not GP, I'll chime in and say I find very limited value in having unit tests and integration tests covering the same ground - and that I'd almost always rather have the integration tests if I'm just going to keep one of them.
There are occasions when I'll mock objects, but it's rare. Working in gamedev, maybe I'm just in an environment where the possible perf/isolation benifits of mocking for the purpouses of isolating a unit just aren't as pronounced?
There are still situations where dependency injection is a wonderful decoupling tool, but I can't even remember the last time I used it exclusively for the purpouses of mocking.
There is a lot of disagreement about what is a unit test outside the realms of academia. The way I'm suggesting may lead to overlapping tests with subcomponents but I would argue that this is OK.
If you have a car and you want to write a unit test for the wheel, does it make sense to stub out the tire? Or if you have a door, should you stub out the door handle in your unit test? I would say no because a good test is still about the functionality of the unit/component.
Testing higher level components doesn't stop you from also writing tests for the tire or for the door handle. If the higher level components have a well abstracted interface, then you should be able to substitute any child component with any other working component later and the higher level component tests should still work without any changes required. You can even change the interface of children/sub-components; doesn't matter, the parent component tests keep working. Note that this is not true if you stub out the children, you need to keep updating the stubs.
The value of the unit test is only as good as the (mock) data you feed it. Your mocked object is great and all your units pass; A user asks for the bathroom and the bar burns down because the bathroom was never mocked. What value was added by that passing unit test?
I wouldn't claim that unit tests are completely sufficient; you clearly also need integration tests. But you don't need all of your tests to be integration tests; in fact that would often be needlessly expensive and annoying.