How exactly works Spring JUnit test that uses stubs?

1.7k Views Asked by At

I am studying for the Spring Core certification and I have some doubts about how exactly works the unit test with stubs.

For example I have the following slide:

enter image description here

So I think that it means that in the production environment I have an AuthenticatorImpl class that use a JpaAccountRepo service\repository that is a dependency and it is itself related to some dependencies and to the prodution environment (Spring, configurations and the DB).

So if I want to test AuthenticatorImpl as a unit I have to remove links to all dependencies.

So using stub way I have to create a stub of the previous first dependency of the unit that I want to test. In this case it is JpaAccountRepo so I can create a generic AccountRepoStub that is a fake implementation that don't use a database and don't use a specific tecnology to access data (I am not testing JpaAccountRepo so I can use a fake implementation because it is a unit test and not an integration test).

Is it my reasoning right untill now?

So for example if this is my AuthenticatorImpl class

public class AuthenticatorImpl implements Authenticator {
    private AccountRepository accountRepository;

    public AuthenticatorImpl(AccountRepository accountRepository) {
        this.accountRepository = accountRepository;
    }

    public boolean authenticate(String username, String password) {
        Account account = accountRepository.getAccount(username);
        return account.getPassword().equals(password);
    }
}

As you can see the constructor AuthenticatorImpl() constructor take a AccountRepository object as paramether (that is an interface and not an implementation).

So I can create my stub class named StubAccountRepository that implement AccountRepository interface

class StubAccountRepository implements AccountRepository {
    public Account getAccount(String user) {
        return “lisa”.equals(user) ? new Account(“lisa”, “secret”) : null;
    }
}

So finnally I can create my unit test implementing an AuthenticatorImplTests class

import org.junit.Before; import org.junit.Test; ...

public class AuthenticatorImplTests {
    private AuthenticatorImpl authenticator;

    @Before 
    public void setUp() {
        authenticator = new AuthenticatorImpl( new StubAccountRepository() );
    }

    @Test 
    public void successfulAuthentication() {
        assertTrue(authenticator.authenticate(“lisa”, “secret”));
    }

    @Test 
    public void invalidPassword() {
        assertFalse(authenticator.authenticate(“lisa”, “invalid”));
    }
}

So in my setUp method I build an AuthenticatorImpl object passing to it my stub StubAccountRepository so I removed the link with the dependency and I am testing only the AuthenticatorImpl unit.

Is it right or am I missing something?

Tnx

1

There are 1 best solutions below

0
On BEST ANSWER

You got it.

Most of the time, you don't create a Stub class explicitely though, but use a mocking framework like Mockito which creates it, dynamically, for you. For example:

AccountRepository stub = mock(AccountRepository.class);
authenticator = new AuthenticatorImpl(stub);

when(stub.getAccount("lisa")).thenReturn(new Account(“lisa”, “secret”));