Spring Data:服务层单元测试

beg*_*er_ 24 java spring unit-testing spring-data

在我的项目中,我在进行单元测试时遇到了麻烦.一个问题是,只进行集成测试要快得多,并且还要测试组件实际上是否一起工作.单元测试新颖的"算法"左右似乎要容易得多.单元测试服务类它只是感觉错误和无用.

我正在使用mockito来模拟spring数据存储库(因此也就是DB访问).问题是如果我告诉模拟的存储库在方法调用getById上返回实体A,它显然会返回它,服务也将返回它.是的,该服务会做一些额外的东西,但是非常小的东西,比如加载延迟集合(来自hibernate).显然我在单元测试中没有任何惰性集合(代理).

例:

@Test
public void testGetById() {
    System.out.println("getById");
    TestCompound expResult = new TestCompound(id, "Test Compound", "9999-99-9", null, null, null);

    TestCompoundRepository mockedRepository = mock(TestCompoundRepository.class);
    when(mockedRepository.findOne(id)).thenReturn(expResult);

    ReflectionTestUtils.setField(testCompoundService, "testCompoundRepository",
            mockedRepository, TestCompoundRepository.class);

    TestCompound result = testCompoundService.getById(id);
    assertEquals(expResult, result);
}
Run Code Online (Sandbox Code Playgroud)

万岁,其余的都成功了.多么惊喜!不是真的没有.

有人可以向我解释我做错了什么吗?或者这样一个测试的重点是什么?我的意思是我告诉返回expResult然后它返回.哇.多么惊喜!感觉就像我在测试mockito是否有效,而不是我的服务.

编辑:

我看到的唯一好处是,如果有些是愚蠢的错误,就像在那里留下一个不需要的行,将返回值设置为null或类似的愚蠢.这种情况将由单元测试捕获."奖励 - 努力"比例看起来还不错吗?

Des*_*der 13

问题可能有点旧,但我会回答以防万一有人偶然发现.

  • 我正在使用Mockito和JUnit.
  • AccountRepository是一个扩展JPARepository的普通spring数据存储库.
  • 帐户是一个普通的JPA实体.

要测试您的服务并模拟Spring Data存储库,您需要以下内容.

package foo.bar.service.impl;

import foo.bar.data.entity.Account;
import foo.bar.data.repository.AccountRepository;
import foo.bar.service.AccountService;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class AccountServiceImplTest {

    @Mock
    private static AccountRepository accountRepository;

    @InjectMocks
    private static AccountService accountService = new AccountServiceImpl();

    private Account account;

    @Test
    public void testFindAccount() {

        Integer accountId = new Integer(1);

        account = new Account();
        account.setId(accountId);
        account.setName("Account name");
        account.setCode("Accont code");
        account.setDescription("Account description");

        Mockito.when(accountRepository.findOne(accountId)).thenReturn(account);

        Account retrivedAccount = accountService.findAccount(accountId);

        Assert.assertEquals(account, retrivedAccount);

    }

}
Run Code Online (Sandbox Code Playgroud)


Kev*_*sox 8

我喜欢测试我的Spring Data存储库的原因之一是测试我已经正确定义了我的JPA映射.我不使用模拟框架进行这些测试,我使用Spring Test框架实际引导容器,允许我将实际存储库自动装入Junit测试,以便我可以对它执行测试.

我同意你的想法,嘲笑存储库是没用的.由于您使用Spring,我建议利用Spring Test框架对您的存储库执行真正的测试,这些测试可以针对嵌入式数据库(如H2)以更多基于单元测试的方式或您的实际数据库实现(如Oracle或MySql)执行.进行更多的集成测试.(针对开发数据库的副本执行这些测试)这些测试将揭示JPA映射和其他项目(例如数据库中不正确的级联设置)中的谬误.

这是我在GitHub上的一个测试的例子.注意框架实际上如何将存储库自动装入测试中.该存储库还包含一个如何配置Spring Test框架的示例,我在本博文中也进行了演示.

总而言之,我不相信您将从使用存储库的模拟测试我已经讨论过的存储库中获得任何好处.

我要添加的另一个注释是,模拟并不是真正用于测试的实际类.它们的用途是为被测试的类提供所需的依赖关系.

  • 一旦您停止嘲笑要测试的类的环境,您就不再进行单元测试了。单元测试的概念是隔离地测试一个单元。如果您想一起测试其他部分,那么您需要编写集成测试 (2认同)