Spring Boot Mockito (二)

news/2024/7/5 8:57:24

Spring Boot Mockito (二)

基于第一篇Spring Boot Mockito (一)
这篇文章主要是讲解Spring boot 与 Mockito 集成持久层接口层单元测试。

1. 引入数据库 h2及其依赖包

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

2. 增加h2的属性配置 application.properties

spring.h2.console.enabled=true

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect

3. 增加Order 的属性限制

public class Order {
	//...
	// 对Order增加注解
    @NotNull
    @NotBlank
    @Size(max = 50)
    @Column(length = 50)
    private String name;
    @NotNull
    private Double price;
	//...

4. 初始化数据

@Component
@RequiredArgsConstructor
public class InitData implements CommandLineRunner {

    private final OrderRepository orderRepository;

    @Override
    public void run(String... args) throws Exception {
        loadOrderData();
    }

    private void loadOrderData() {
        if (orderRepository.count() == 0) {
            Order order1 = Order.builder()
                    .id(1001L).name("Moon chairs")
                    .price(58.0)
                    .createTime(LocalDateTime.of(2024, 04, 01, 22, 10, 10))
                    .build();
            Order order2 = Order.builder()
                    .id(1002L).name("Outdoor canopy black coating")
                    .price(98.0)
                    .createTime(LocalDateTime.of(2024, 04, 01, 22, 10, 10))
                    .build();
            Order order3 = Order.builder()
                    .id(1003L).name("Outdoor canopy silver coating")
                    .price(48.0)
                    .createTime(LocalDateTime.of(2024, 04, 01, 22, 10, 10))
                    .build();
            orderRepository.save(order1);
            orderRepository.save(order2);
            orderRepository.save(order3);
        }
    }
}

5. 新建持久层单元测试

@DataJpaTest
@Import(InitData.class)
public class OrderRepositoryTest {

    @Autowired
    OrderRepository orderRepository;

    @Test
    void test_findAllByNameLike() {
        List<Order> list = orderRepository.findAllByNameLike("%Outdoor%");
        assertEquals(2, list.size());
    }

    @Test
    void test_findAllByNameLike_Empty() {
        List<Order> list = orderRepository.findAllByNameLike("%Outdoor folding chair%");
        assertEquals(0, list.size());
    }

    @Test
    void test_findAllByPriceLessThan() {
        List<Order> list = orderRepository.findAllByPriceLessThan(50d);
        assertEquals(1, list.size());
    }

    @Test
    void test_findAllByPriceLessThan_Empty() {
        List<Order> list = orderRepository.findAllByPriceLessThan(10d);
        assertEquals(0, list.size());
    }

    @Test
    void test_saveOrder() {
        Order order4 = Order.builder()
                .id(1004L).name("Outdoor folding chair")
                .price(28.0)
                .createTime(LocalDateTime.of(2024, 04, 01, 22, 10, 10))
                .build();
         orderRepository.save(order4);
        long count = orderRepository.count();
        assertEquals(4, count);
    }

    @Test
    void test_saveOrder_NameIsTooLong() {
        Order order4 = Order.builder()
                .id(1004L).name("Outdoor folding chair Outdoor folding chair Outdoor folding chair Outdoor folding chair Outdoor folding chair")
                .price(28.0)
                .createTime(LocalDateTime.of(2024, 04, 01, 22, 10, 10))
                .build();
        order4 = orderRepository.save(order4);
        try {
            orderRepository.flush();
            fail("Name is null");
        } catch (ConstraintViolationException cve) {
            assertTrue(validate(cve, "size must be between 0 and 50", "name"));
        }
    }

    @Test
    void test_saveOrder_NameIsNull() {
        Order order4 = Order.builder()
                .id(1004L)
                .price(28.0)
                .createTime(LocalDateTime.of(2024, 04, 01, 22, 10, 10))
                .build();
        try {
            order4 = orderRepository.save(order4);
            orderRepository.flush();
            fail("Name is null");
        } catch (ConstraintViolationException cve) {
            assertTrue(validate(cve, "must not be null", "name"));
        }
    }

    private boolean validate(ConstraintViolationException cve, String message, String fieldName) {
        return cve.getConstraintViolations().stream()
                .anyMatch(e -> {
                    boolean hasMessage = e.getMessage().contains(message);
                    Iterator<Path.Node> itr = e.getPropertyPath().iterator();
                    boolean matchedFieldName = false;
                    while (itr.hasNext()) {
                        Path.Node pNode = itr.next();
                        matchedFieldName = pNode.getName().equals(fieldName);
                        if (matchedFieldName) {
                            break;
                        }
                    }
                    return hasMessage && matchedFieldName;
                });
    }
}

在这里插入图片描述


http://lihuaxi.xjx100.cn/news/2144984.html

相关文章

目标检测——车牌数据集

一、重要性及意义 交通安全与管理&#xff1a;车牌检测和识别技术有助于交通管理部门快速、准确地获取车辆信息&#xff0c;从而更有效地进行交通监控和执法。例如&#xff0c;在违规停车、超速行驶等交通违法行为中&#xff0c;该技术可以帮助交警迅速锁定违规车辆&#xff0…

Francek Chen 的128天创作纪念日

目录 Francek Chen 的128天创作纪念日机缘收获日常成就憧憬 Francek Chen 的128天创作纪念日 Francek Chen 的个人主页 机缘 不知不觉的加入CSDN已有两年时间了&#xff0c;最初我第一次接触CSDN技术社区是在2022年4月的时候&#xff0c;通过学长给我们推荐了几个IT社区平台&a…

反套路修仙国漫崛起,诛仙受热议,但这一部才是最大黑马

近日《诛仙》动漫第二季开播&#xff0c;又有新的修仙番可以追了&#xff0c;《诛仙》还因为反套路的剧情引起了漫迷们热烈的讨论。其实目前在播的修仙国漫中&#xff0c;有几部反套路程度不输诛仙&#xff0c;而且有一部可能会成为最大黑马&#xff0c;下面就一起来看看吧&…

Autodesk Maya 2025 Multilanguage (macOS, Linux, Windows) - 三维动画和视觉特效软件

Autodesk Maya 2025 Multilanguage (macOS, Linux, Windows) - 三维动画和视觉特效软件 三维计算机动画、建模、仿真和渲染软件 请访问原文链接&#xff1a;https://sysin.org/blog/autodesk-maya/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&a…

【树上倍增】【内向基环树】【 图论 】2836. 在传球游戏中最大化函数值

本文涉及知识点 树上倍增 内向基环树 图论 LeetCode2836. 在传球游戏中最大化函数值 给你一个长度为 n 下标从 0 开始的整数数组 receiver 和一个整数 k 。 总共有 n 名玩家&#xff0c;玩家 编号 互不相同&#xff0c;且为 [0, n - 1] 中的整数。这些玩家玩一个传球游戏&am…

求一个3*3的整型矩阵对角线元素之和

#include <stdio.h> // 标准输入输出头文件 int main(){int a[3][3],sum0; // 声明一个3x3的矩阵a和一个整型变量sum用于存储对角线元素之和int i,j;printf("请输入对角线元素&#xff1a;\n"); // 提示用户输入对角线元素// 循环读取用户输入的对角线元素for…

【C++练级之路】【Lv.18】哈希表(哈希映射,光速查找的魔法)

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、哈希1.1 哈希概念1.2 哈希函数1.3 哈希冲突 二、闭散列2.1 数据类型2.2 成员变量2.3 默认成员函数2.…

【C++风云录】从SQLite到Redis:探索C++与多种数据库的交互之道

开启数据库之旅&#xff1a;通过C与各种数据库交互&#xff0c;事半功倍 数据库操作&#xff1a;介绍与应用 前言 在现代软件开发中&#xff0c;数据库扮演着至关重要的角色&#xff0c;用于存储和管理大量的数据。为了更有效地操作数据库&#xff0c;开发人员常常依赖于专门…