0

I was wondering if I wrote this test in a proper way to mock a real situation. Can you please provide any feedback?

I'm using Mockito in a Spring Boot environment. I'm new to Mockito and other mocking techniques, but I want to know if I'm on the right path or not.

@RunWith(MockitoJUnitRunner.class)
@SpringBootTest
class FileServiceImplTest {
    @Mock
    private UserPrincipal userPrincipal;
    @Mock
    private User user;
    @Mock
    private FileService fileService;

    @BeforeEach
    void initialize() {
        user = new User("testUser", "test@email.com", "testPassword");
        user.setId(1L);
        user.setRoles(List.of(Role.User));
        userPrincipal = UserPrincipal.create(user);
    }

    @Test
    void usedMockUpsShouldNotBeNull() {
        assertAll("All mock instaces of classes should not be null",
                () -> assertNotNull(fileService),
                () -> assertNotNull(userPrincipal),
                () -> assertNotNull(user)
        );
    }

    @Test
    void collectionOfFilesShouldChangeAfterNewFileIsAdded_Mockito() throws ExecutionException, InterruptedException {
        Image image = createImageFile();
        List<? super File> files = createFilesCollection();

        doReturn(files).when(fileService).getAll(userPrincipal);
        int initialSize = fileService.getAll(userPrincipal).size();

        fileService.save(image);
        doReturn(files.add(image)).when(fileService).save(image);
        int newSize = fileService.getAll(userPrincipal).size();

        assertNotEquals(newSize, initialSize);
        Mockito.verify(fileService, atLeast(2)).getAll(userPrincipal);
        Mockito.verify(fileService).save(image);
    }
}
Ken Chan
  • 84,777
  • 26
  • 143
  • 172
  • 1
    `@SpringBootTest` is supposed to be used to do Integration Tests. When you do Integration Tests you usually don't want to mock stuff. Consider implementing Unit Tests instead and taking a look at https://stackoverflow.com/questions/5357601/whats-the-difference-between-unit-tests-and-integration-tests / https://dzone.com/articles/unit-and-integration-tests-in-spring-boot-2 / https://www.baeldung.com/spring-boot-testing. – João Dias Jan 15 '22 at 00:57
  • To add to what Joao mentioned above: using spring boot tests will slow down your tests considerably, so use it sparingly. – Augusto Jan 15 '22 at 13:03

1 Answers1

2

I am sorry that you are in the wrong path.

If FileService is just an interface, you do not need to test it.

If FileService is an implementation, you should create an actual instance to test it but not a mock.

The mock is only useful for the direct dependencies of the class that you are testing (i.e FileSerivice) such that you can easily stub the result when calling methods on these dependencies and verify if the class you are testing interacts with them correctly. (i.e. call the correct methods with the correct parameters etc.)

As I cannot see FileSerivice 's source codes , but if UserPrincipal and User are not its dependencies , it does not make sense to mock them.

Also as mentioned by other in the comment, as you are not doing the integration testing with some Spring framework stuff, you should simply rewrite your test as a plain Mockito test which is simpler and run faster :

@ExtendWith(MockitoExtension.class)
public class FileServiceImplTest {


}
Ken Chan
  • 84,777
  • 26
  • 143
  • 172
  • Hi thanks for your reply, I appreciate it. My intention was to test the actual FileServiceImpl(ementation). From what I understand now is that I should create an actual instace of it, got it. So when using the '@ExtendWith(MockitoExtension.class)', can you provide me an example for my situation? Because I'm really new to this world of working with Java annotations, especially in testing stuff. – user16906859 Jan 15 '22 at 23:27