测试与 db 的连接,测试通过但没有在 db 中创建新实例

Posted

技术标签:

【中文标题】测试与 db 的连接,测试通过但没有在 db 中创建新实例【英文标题】:Testing connectiong with db, tests passes but no new instance in db created 【发布时间】:2018-05-11 04:13:06 【问题描述】:

我想做什么:我想测试我的应用是否与数据库正确连接。为了做到这一点,我使用了这些教程:http://www.baeldung.com/spring-boot-testinghttp://www.baeldung.com/spring-testing-separate-data-source 所以我正在创建新的 testUser,保存它并检查 userName 找到的用户是否等于我保存的那个。

什么不工作:即使测试通过,数据库中也不会出现新用户。我不知道为什么。有什么建议吗?

测试:

package com.shareabook.integration.user;

import com.shareabook.constants.initialNumberOfPoints;
import com.shareabook.model.Points;
import com.shareabook.model.User;
import com.shareabook.repository.PointsRepository;
import com.shareabook.repository.RoleRepository;
import com.shareabook.repository.UserRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Arrays;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@DataJpaTest
public class userTest 
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PointsRepository pointsRepository;

    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Test
    public void whenFindByUserName_thenReturnUser() 
        //given
        User testUser = new User();

        // Creates new points instance
        Points points = new Points();
        points.setAmountOfPoints(initialNumberOfPoints.INITIAL_NUMBER_OF_POINTS.getInitialNumberOfPoints());
        pointsRepository.save(points);
        int tempId = points.getId();

        testUser.setUserName("userName");
        testUser.setFirstName("firstName");
        testUser.setLastName("lastName");
        testUser.setPassword(passwordEncoder.encode("P@ssword123"));
        testUser.setEmail("emal@email.com");
        testUser.setIsBlocked(false);
        testUser.setIdpoints(tempId);
        testUser.setRoles(Arrays.asList(roleRepository.findByRole("USER")));

        userRepository.save(testUser);

        //when
        User found = userRepository.findByUserName(testUser.getUserName());

        //then
        assertThat(found.getUserName()).isEqualTo(testUser.getUserName());


    

-----编辑---------- 在 cmets 提供有用的建议后,我稍微更改了测试,现在它按预期工作。

package com.shareabook.integration.user;

import com.shareabook.constants.initialNumberOfPoints;
import com.shareabook.model.Points;
import com.shareabook.model.User;
import com.shareabook.repository.PointsRepository;
import com.shareabook.repository.RoleRepository;
import com.shareabook.repository.UserRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

@RunWith(SpringRunner.class)
@SpringBootTest
public class userTest 
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PointsRepository pointsRepository;

    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    @Test
    public void whenFindByUserName_thenReturnUser() 
        //given
        User testUser = new User();

        // Creates new points instance
        Points points = new Points();
        points.setAmountOfPoints(initialNumberOfPoints.INITIAL_NUMBER_OF_POINTS.getInitialNumberOfPoints());
        pointsRepository.save(points);
        int tempId = points.getId();

        testUser.setUserName("userName");
        testUser.setFirstName("firstName");
        testUser.setLastName("lastName");
        testUser.setPassword(passwordEncoder.encode("P@ssword123"));
        testUser.setEmail("emal@email.com");
        testUser.setIsBlocked(false);
        testUser.setIdpoints(tempId);
        testUser.setRoles(Arrays.asList(roleRepository.findByRole("USER")));

        userRepository.save(testUser);

        //when
        User found = userRepository.findByUserName(testUser.getUserName());

        //then
        assertNotNull(found);
        assertEquals(testUser.getUserName(), found.getUserName());
    

【问题讨论】:

我想知道它是否与 DataJpaTest 注释有关。来自文档(docs.spring.io/spring-boot/docs/current/api/org/springframework/…) - “默认情况下,使用 @DataJpaTest 注释的测试将使用嵌入式内存数据库(替换任何显式或通常自动配置的数据源)。”听起来您希望在数据库中进行实际更改,但我怀疑您实际上是在查询内存中的。 @NickDeFazio,谢谢,你和 SimonMartinelli 是对的。 【参考方案1】:

@DataJpaTest 将配置一个内存嵌入式数据库,扫描@Entity 类并配置 Spring Data JPA 存储库。

它是事务性的,但会在每次测试结束时回滚!

这就是您的数据库中没有数据的原因。

【讨论】:

谢谢你,@SimonMartinelli。所以总结一下 - 我正在测试内存数据库中的操作,而不是与我的数据库的实际连接,是吗? 可以,只要您没有配置其他任何东西

以上是关于测试与 db 的连接,测试通过但没有在 db 中创建新实例的主要内容,如果未能解决你的问题,请参考以下文章

为PyCharm设置DB Navigator(SQLite)

如何告诉Liquibase忽略db.changelog * .xml?

测试 OLE DB 连接字符串的快速方法

Django 测试因 InternalError 失败:没有这样的保存点。 DB:Postgres,通过 mysql

通过 Oracledb Driver 使用 Nodejs 连接到远程 Oracle DB

Go 测试失败 db 查询(零指针)但适用于 Postman/Curl