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:
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
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: