Unit-testing – Are Integration Tests Meant to be Redundant

integration-testsunit testing

Here is some fake code under test:

public void saveItem() {
  try {
    databaseInterface.saveItemToDatabase(item);
  } catch (Exception e) {
      // deal with it 
      return;
  }
  itemList.Add(item);
}

When writing a unit test, if you were to not stub out that database call, test engineers would say that it is an integration test, not a unit test since it is calling a real database which makes the unit test slow, and a characteristic of a unit test is that it should be fast.

So, you stub out that database call, and test whether the item was saved to the list, ending up with a unit test.

You also create a unit test to test whether the saveItemToDatabase function was actually called, so in this new unit test you decide to mock the call and assert against it.

You are also tasked with unit testing your database interface, to make sure that items are actually being saved to the database, so you do so.

All your tests pass, so now you know that 1) items are being saved to the list 2) your saveItemToDatabase method is actually being called 3) your unit tests covering your database module show that the item is actually being saved to the database.

If I'm understanding integration test correctly, you would in an integration test, test all of these things, this time using a real database call in one test. So in one integration test your test might do the following:

  1. Create an item.
  2. Call saveItem() (an object method) which will save the item you just created.
  3. Query the database for the item using your database interface.
  4. Check that the item you created and the query result are equal.
  5. Check that the item you saved was added to the itemList.

It seems like the integration test is taking all the unit tests and rechecking what each unit test does, except this time you aren't stubbing or mocking anything out, so it makes it seem like integration tests are a bit redundant.

Am I misunderstanding what an integration test is? It sort of seems like a test that says, "yes, your production code is actually working when you don't stub or mock things out."

Best Answer

It sort of seems like a test that says, "yes, your production code is actually working when you don't stub or mock things out."

That's exactly what it is.

Stubs and mocks isolate the infrastructure from your unit tests, which means that your units get tested, but not the infrastructure that you've stubbed out, nor the connections your units make with that infrastructure. It's the behavior of your units and the way that behavior interacts with the actual components that you've stubbed out that is being tested in an integration test.

Remember, stubs and mocks don't represent the actual behavior of a real system; they only simulate a small number of artificially-induced behaviors so that you can run your unit tests. An integration test not only provides a more realistic exercise of the system, but also a more comprehensive one.