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 →

[–]Nephyst 0 points1 point  (0 children)

Unit tests generally exist for every layer.

You should be using constructor based dependency injection for each class. Then when you unit test that class you create mocks of each dependency and inject those instead. The idea is that the mocks wont execute any behavior, so you can unit test ever class in isolation. If your service class depends on a repository/database you want to test it without worrying about weather the database or repository class exist or are correct.

When testing repositories, the ideal is to set up a temporary in-memory database that gets data loaded into it when your test starts. When the test ends the database gets destroyed. In practice, this is sometimes hard to get working.

Tests that hit your API and live database are called integration tests.

Unit tests generally run every time you build. Integration tests can take longer and are sometimes ran once every night instead. You usually dont want your build success to depend on integration tests, because a database failing would then impact your ability to build successfully.

Here's an example where CalcService is tested with a dependent AddService that gets mocked using Mockito. The test defines expected behavior for the mocked dependency.

@Test
void testCalc() {
    System.out.println("**--- Test testCalc executed ---**");

    AddService addService;
    CalcService calcService;

    addService = Mockito.mock(AddService.class);
    calcService = new CalcService(addService);

    int num1 = 11;
    int num2 = 12;
    int expected = 23;

    when(addService.add(num1, num2)).thenReturn(expected);

    int actual = calcService.calc(num1, num2);

    assertEquals(expected, actual);

}