Spring 单元测试 JPA 存储库
Posted
技术标签:
【中文标题】Spring 单元测试 JPA 存储库【英文标题】:Spring Unit test JPA repository 【发布时间】:2014-08-13 14:54:27 【问题描述】:我是 Spring 框架的新手。我需要为 JPA 存储库编写单元测试。我正在尝试简单的存储库saveAndFlush()
方法。但是我的存储库中没有任何内容。这是我的源代码:
TestContext.class
@Configuration
@PropertySource("classpath:log4j.properties")
public class TestContext
@Bean
public RoleService roleService()
return Mockito.mock(RoleService.class);
@Bean
public RightService RightService()
return Mockito.mock(RightService.class);
@Bean
public RoleRepository RoleRepository()
return Mockito.mock(RoleRepository.class);
RoleServiceTest.class
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestContext.class)
@WebAppConfiguration
public class RoleServiceTest
@Autowired
private RoleRepository roleRepository;
@Test
public void TestServices() throws Exception
RoleDetails first = new RoleDetails();
first.setId("1");
first.setDescription("First Description");
first.setName("First");
roleRepository.saveAndFlush(new RoleEntity(first));
roleRepository.save(new RoleEntity(first));
List<RoleEntity> roles = new ArrayList<RoleEntity>();
roles = roleRepository.findAll();
System.out.println(roles);
assertEquals(1, roles.size());
还有错误:
java.lang.AssertionError: expected:<1> but was:<0>
我几乎可以肯定问题是由于 testContext.Class 而发生的。我使用这个类来测试我的控制器,它运行良好,但现在我需要测试我的数据库,我不知道如何修改 contextConfiguration。我希望有人能帮助我。提前致谢!
【问题讨论】:
【参考方案1】:问题确实来自 TestContext。您尝试使用模拟对象保存对象,这是不正确的。
解决方案是使用真实的存储库。为此,您需要执行以下步骤:
-
使用 @Repository 注释注释您的 RoleRepository 并使用 JpaRepository(RoleEntity,ID) 扩展类(其中 ID 是您声明 RoleEntity id 的类型) .
将 RoleRepository 添加到您的上下文配置类(真正的,而不是测试的)。您可以通过添加 @EnableJpaRepositories(value="your.repository.package") 来做到这一点。
将 RoleServiceTest 类上 @ContextConfiguration 注释中的 TestContext.class 替换为您用于配置基于 Spring 的项目的真实上下文配置类。
希望我的回答对你有帮助,如果您还需要帮助,请随时再次提问!
【讨论】:
真实的在哪里,测试的上下文配置类在哪里?【参考方案2】:您的存储库是一个模拟对象。根据定义,模拟对象是一个不做它通常应该做的事情,而是做你在测试中告诉它做的事情的对象。
要测试存储库,存储库必须是真实的。因此,您的上下文类应该有
@Bean
public RoleRepository RoleRepository()
return new RoleRepositoryImpl(); // or whatever the class implementing the repository is
【讨论】:
这在技术上是正确的,但是很多 Spring 数据存储库使用自动实现逻辑来进行基本的 CRUD 操作。试图直接实例化它们是行不通的;你应该展示如何使用@Autowired
或@Resource
来获取它们。【参考方案3】:
如果使用 Spring Boot,创建一个 Web 应用程序并且您正在运行 Application.class 中的 main() 方法,您可以使用:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class MyUnitTest
Some someInstance = new Some();
@Autowired
private SomeRepository someRepository;
@Test
public void testSomeClass() throws Exception
Some savedSome = someRepository.save(someInstance);
assertEquals(1, someRepository.count());
【讨论】:
这实际上是一个集成测试而不是单元测试,对吧?用于单元测试的 mockito 运行器,用于集成的 springjunit 运行器以上是关于Spring 单元测试 JPA 存储库的主要内容,如果未能解决你的问题,请参考以下文章
对 Spring Data JPA @Query 进行单元测试是不可能的,真的吗?
Spring Boot中JPA Repository的Save方法的单元测试