使用存根的Spring JUnit测试究竟如何工作?

时间:2014-11-23 12:51:44

标签: java spring unit-testing junit spring-test

我正在攻读Spring Core认证,我对单元测试存根的确切运作方式存在疑问。

例如,我有以下幻灯片:

enter image description here

所以我认为这意味着在生产环境中我有一个 AuthenticatorImpl 类,它使用 JpaAccountRepo service \ repository 依赖,它是 本身与一些依赖关系和生产环境(Spring,配置和数据库)有关。

因此,如果我想测试 AuthenticatorImpl 作为单元,我必须删除指向所有依赖项的链接

因此,使用 stub 方式,我必须创建我想要测试的单元的前一个依赖项的存根。在这种情况下,它是 JpaAccountRepo ,所以我可以创建一个通用的 AccountRepoStub ,这是一个虚假的实现,不使用数据库并且不使用特定的tecnology访问数据(我没有测试 JpaAccountRepo 所以我可以使用假实现,因为它是单元测试而不是集成测试)。

这是我的推理权,直到现在还在吗?

例如,如果这是我的 AuthenticatorImpl

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);
    }
}

正如您所见,构造函数 AuthenticatorImpl()构造函数将 AccountRepository 对象作为参数(即接口而非实现)。

所以我可以创建名为 StubAccountRepository 存根类来实现 AccountRepository 接口

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

所以我最终可以创建单元测试来实现 AuthenticatorImplTests

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”));
    }
}

所以在我的 setUp 方法中,我构建了一个 AuthenticatorImpl 对象,并将其传递给我的存根 StubAccountRepository ,所以我删除了依赖项的链接我只测试 AuthenticatorImpl 单元。

是对还是我错过了什么?

TNX

1 个答案:

答案 0 :(得分:3)

你明白了。

大多数时候,你没有明确地创建一个Stub类,但是使用像Mockito这样的模拟框架,动态地为你创建它。例如:

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

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