Search code examples
unit-testingintegration-testingdatabase-testing

Unit Testing and Integration Testing examples


I have created following four tests in a Test class that tests a findCompany() method of a CompanyService.

@Test
public void findCompany_CompanyIdIsZero() {
    exception.expect(IllegalArgumentException.class);
    companyService.findCompany(0);
}
@Test
public void findCompany_CompanyIdIsNegative() {
    exception.expect(IllegalArgumentException.class);
    companyService.findCompany(-100);
}
@Test
public void findCompany_CompanyIdDoesntExistInDatabase() {
    Company storedCompany = companyService.findCompany(100000);
    assertNull(storedCompany1);
}

@Test
public void findCompany_CompanyIdExistsInDatabase() {
    Company company = new Company("FAL", "Falahaar");

    companyService.addCompany(company);

    Company storedCompany1 = companyService.findCompany(company.getId());
    assertNotNull(storedCompany1);
}

My understanding says that the first three of these are unit tests. They test the behavior of the findCompany() method, checking how the method will respond on different inputs. The fourth test, though placed in the same class, actually seems to be an integration test to me. It requires a Company to be added to the database first, so that it can be found later on. This introduces external dependencies - addCompany() and database.

Am I going right? If yes, then how should I unit test finding an existing object? Just mock the service to "find" one? I think that kills the intent of the test.

I appreciate any guidance here.


Solution

  • I look at it this way: the "unit" you are testing here is the CompanyService. In this sense all of your tests look like unit tests to me. Underneath your service, though, there may be another service (you mention a database) that this test is also exercising? This could start to blur the lines with integration testing a bit, but you have to ask yourself if it matters. You could stub out any such underlying service, and you may want to if:

    1. The underlying service is slow to set up or use, making your unit tests too slow.
    2. You want to be sure the behaviour of this test is unaffected by the underlying service - i.e. this test should only fail if there is a bug in CompanyService.

    In my experience, provided the underlying service is fast enough I don't worry too much about my unit test relying on it. I don't mind a bit of integration leaking into my unit tests, as it has benefits (more integration coverage) and rarely causes a problem. If it does cause problems you can always come back to it and add stubbing to improve the isolation.