【问题标题】:How exactly works Spring JUnit test that uses stubs?使用存根的 Spring JUnit 测试究竟是如何工作的?
【发布时间】:2026-01-14 01:00:02
【问题描述】:

我正在学习 Spring Core 认证,但我对 单元测试stubs 的具体工作方式有一些疑问。

例如我有以下幻灯片:

所以我认为这意味着在 生产环境 我有一个 AuthenticatorImpl 类,它使用一个 JpaAccountRepo 服务\存储库,它是一个依赖,它是 本身与一些依赖项和生产环境(Spring、配置和数据库)相关。

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

因此,使用 stub 方式,我必须为要测试的单元的前一个第一个依赖项创建一个存根。在这种情况下,它是 JpaAccountRepo,所以我可以创建一个通用的 AccountRepoStub,它是一个不使用数据库且不使用特定技术来访问数据的假实现(我没有测试 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 对象作为参数(这是一个接口而不是实现)。

所以我可以创建名为 StubAccountRepositorystub 类来实现 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

【问题讨论】:

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


    【解决方案1】:

    你明白了。

    大多数时候,您不会显式地创建 Stub 类,而是使用像 Mockito 这样的模拟框架,它会动态地为您创建它。例如:

    AccountRepository stub = mock(AccountRepository.class);
    authenticator = new AuthenticatorImpl(stub);
    
    when(stub.getAccount("lisa")).thenReturn(new Account(“lisa”, “secret”));
    

    【讨论】: