One of my co-workers maintains that integration tests are all kinds of bad and wrong - everything must be unit-tested, which means you have to mock dependencies; an option which, for various reasons, I'm not very fond of.
I find that, in some cases, a unit-test simply doesn't prove anything.
Let's take the following (naive) repository implementation (in PHP) as an example:
<!-- language: php -->
class ProductRepository
{
private $db;
public function __construct(ConnectionInterface $db) {
$this->db = $db;
}
public function findByKeyword($keyword) {
return $this->db->fetch("SELECT * FROM products p"
. " WHERE p.name LIKE :keyword", ['keyword' => $keyword]);
}
}
Let's say I want to prove in a test that this repository can actually find products matching various given keywords.
Short of integration testing with a real connection object, how can I know that this is actually generating real queries - and that those queries actually do what I think they do?
If I have to mock the connection object in a unit-test, I can only prove things like "it generates the expected query" - but that doesn't mean it's actually going to *work*... that is, maybe it's generating the query I expected, but maybe that query doesn't do what I think it does.
In other words, I feel like a test that makes assertions about the generated query, is essentially without value, because it's testing how the `findByKeyword()` method was *implemented*, but that doesn't prove that it actually *works*.
This problem isn't limited to repositories or database integration - it seems to apply in a lot of cases, where making assertions about the use of a mock (test-double) only proves how things are implemented, not whether they're going to actually work.
How do you deal with situations like these?
Are integration tests really "bad" in a case like this?
I get the point that it's better to test one thing, and I also understand why integration testing leads to myriad code-paths, all of which cannot be tested - but in the case of a service (such as a repository) whose only purpose is to interact with another component, how can you really test anything without integration testing?