Spring单元测试JPA仓库

10

我是Spring框架的新手。我需要为JPA repository编写单元测试。我正在尝试简单的saveAndFlush()方法。但我的repository中没有保存任何内容。这是我的源代码:

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。希望有人能帮助我。谢谢!

3个回答

9
问题确实出在TestContext上。你试图使用模拟对象来保存你的对象,这是不正确的。
解决方法是使用真正的存储库。为此,您需要按照以下步骤进行操作:
1. 使用@Repository注释您的RoleRepository,并将该类扩展为JpaRepository(RoleEntity,ID)(其中ID是您声明的RoleEntity的id类型)。 2. 将RoleRepository添加到您的Context Configuration类中(真正的类,而不是测试类)。您可以通过添加@EnableJpaRepositories(value="your.repository.package")来实现这一点。 3. 在RoleServiceTest类中,使用您用于配置基于Spring的项目的真正的Context Configuration类替换@ContextConfiguration注释中的TestContext.class。
希望我的回答有所帮助,如果您仍需要帮助,可以随时再次提问!

真实的和测试的上下文配置类在哪里? - Salman S

5

你的仓库是一个模拟对象。按照定义,模拟对象是一个不执行正常任务的对象,而是在测试中执行你指定的任务。

为了测试仓库,仓库必须是真实的。因此,你的上下文类应该有:

@Bean
public RoleRepository RoleRepository() {
    return new RoleRepositoryImpl(); // or whatever the class implementing the repository is 
}

2
这在技术上是正确的,但很多Spring数据仓库使用自动实现逻辑来进行基本的CRUD操作。直接尝试实例化它们是行不通的;你应该展示如何使用@Autowired@Resource获取它们。 - Patrick M

1
如果使用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());
}

1
这基本上将成为一个集成测试,而不是单元测试,对吗?Mockito Runner用于单元测试,SpringJUnit Runner用于集成测试。 - wired00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接