当前位置: 首页 > news >正文

Spcok测试代码抛异常场景

测试代码抛异常场景

`class ExceptionSpec extends Specification {def validateService = new ValidateService()@Unrolldef "验证UserInfo"() {when: "调用校验方法"validateService.validateUser(user)then: "捕获异常并设置需要验证的异常值"def exception = thrown(expectedException)exception.errorCode == expectedErrCodeexception.errorMessage == expectedMessagewhere: "验证用户的合法性"user                || expectedException | expectedErrCode | expectedMessagenull                || APIException      | "1001"          | "userInfo is null"new UserInfo(0, "") || APIException      | "1002"          | "id is not legal"new UserInfo(1, "") || APIException      | "1003"          | "name is not legal"}
}` 

Spock内置thrown()方法,可以捕获调用业务代码抛出的预期异常并验证,再结合where表格的功能,可以很方便的覆盖多种自定义业务异常。

then​标签里用到了Spock的thrown()​方法,这个方法可以捕获我们要测试的业务代码里抛出的异常。thrown()​方法的入参expectedException​,是我们自己定义的异常变量,这个变量放在where​标签里就可以实现验证多种异常情况的功能。expectedException​类型调用validateUser​方法里定义的APIException​异常,可以验证它所有的属性,errorCode​、errorMessage​是否符合预期值。

注意事项

在Spock中,异常条件(如thrown​和notThrown​)只能在then​块的顶层使用,不能嵌套在其他控制结构(如if​语句)中。这意味着你不能在if​语句内部使用thrown​方法。

为了测试不同输入数据下的方法行为,包括抛出异常和不抛出异常的情况,你需要将这些测试拆分为单独的测试用例。每个测试用例只测试一种情况:要么是抛出异常,要么是不抛出异常。

测试案例代码

// 测试捕获异常 RuntimeException 异常def "checkUrlThrowException"() {given:SSRFUtilwhen:SSRFUtil.checkUrl(requestUrl)then:def exception = thrown(expectedException)where:requestUrl          || expectedException"https://baidu.com" || RuntimeException}// 测试不抛异常def "checkUrlNotException"() {given:SSRFUtilwhen:SSRFUtil.checkUrl(requestUrl)then:def exception = notThrown(expectedException)where:requestUrl                                  || expectedException"https://xxx.aaa.com/xxx/xxxx.xlsx"     || null"https://xxx.aaa.net/xxx/xxxx.xlsx"     || null"https://xxx.vip.aaa.com/xxx/xxxx.xlsx" || null}

其它

下面的案例来自于 小美智能助理 的答案.

在Spock中,where​块用于数据驱动测试,通过提供多个输入数据集来测试方法的行为。在测试方法不抛出异常的情况下,可以在then​块中使用notThrown​方法来验证没有异常被抛出。你可以结合where​块和notThrown​方法来测试方法在不同输入数据下的行为。

以下是一个示例,展示了如何在where​块中测试方法在不同输入数据下不抛出异常的情况。

示例代码

假设你有一个Calculator​类,它的divide​方法在除以零时会抛出一个IllegalArgumentException​,在其他情况下正常工作。

class Calculator {int divide(int a, int b) {if (b == 0) {throw new IllegalArgumentException("Division by zero")}return a / b}
}

你可以使用where​块来测试divide​方法在不同输入数据下的行为,不抛出异常的情况如下:

import spock.lang.Specification
import spock.lang.Unrollclass CalculatorSpec extends Specification {@Unrolldef "should return correct result when dividing #a by #b"() {given:def calculator = new Calculator()when:def result = calculator.divide(a, b)then:result == expectednotThrown(Exception)where:a | b || expected10 | 2 || 515 | 3 || 520 | 4 || 5}
}

在这个示例中:

  • @Unroll​注解用于展开每个数据驱动的测试用例,以便更好地查看每个测试用例的结果。
  • where​块定义了测试数据,包括输入参数a​和b​以及期望的结果expected​。
  • then​块中,我们验证result​是否等于期望值,并确保没有抛出任何异常。
结合测试抛异常和不抛异常

你还可以在同一个测试方法中结合测试方法抛出异常和不抛出异常的情况:

import spock.lang.Specification
import spock.lang.Unrollclass CalculatorSpec extends Specification {@Unrolldef "should handle division correctly for a=#a and b=#b"() {given:def calculator = new Calculator()when:def result = calculator.divide(a, b)then:if (b == 0) {def e = thrown(IllegalArgumentException)e.message == "Division by zero"} else {result == expectednotThrown(Exception)}where:a | b || expected10 | 2 || 510 | 0 || _15 | 3 || 520 | 4 || 5}
}

在这个示例中:

  • @Unroll​注解用于展开每个数据驱动的测试用例,以便更好地查看每个测试用例的结果。

  • where​块定义了测试数据,包括输入参数a​和b​以及期望的结果expected​。

  • then​块中,我们使用了条件语句来分别处理抛出异常和不抛出异常的情况。

    • 如果b == 0​,我们期望抛出IllegalArgumentException​,并验证异常的消息内容。
    • 否则,我们验证result​是否等于期望值,并确保没有抛出任何异常。

通过这种方式,你可以在数据驱动的测试中测试方法在不同输入数据下是否抛出异常或不抛出异常,并验证方法的行为是否符合预期。

相关文章:

Spcok测试代码抛异常场景

测试代码抛异常场景 ‍ class ExceptionSpec extends Specification {def validateService new ValidateService()Unrolldef "验证UserInfo"() {when: "调用校验方法"validateService.validateUser(user)then: "捕获异常并设置需要验证的异常值&qu…...

【漏洞复现】脸爱云一脸通智慧管理平台 SystemMng 管理用户信息泄露漏洞(XVE-2024-9382)

0x01 产品简介 脸爱云一脸通智慧管理平台是一套功能强大,运行稳定,操作简单方便,用户界面美观,轻松统计数据的一脸通系统。无需安装,只需在后台配置即可在浏览器登录。 功能包括:系统管理中心、人员信息管理中心、设备…...

新手如何入门Web3?

一、什么是Web3? Web3是指下一代互联网,它基于区块链技术,致力于将各种在线活动变得更加安全、透明和去中心化。Web3是一个广义的概念,涵盖了包括数字货币、去中心化应用、智能合约等在内的多个方面。它的主要特点包括去中心化、…...

React.FC`<ChildComponentProps>`解释

代码场景 ParentComponent.tsx import React, { useState } from react; import ChildComponent from ./ChildComponent;function ParentComponent() {const [childData, setChildData] useState<string>();const handleChildData (data: string) > { // 可以直接…...

2024-06-24力扣每日一题

链接&#xff1a; 503. 下一个更大元素 II 题意 循环数组&#xff0c;找出每个元素的往后最近且大于它的元素 解&#xff1a; 今天没试暴力啊&#xff0c;大概率是过不了的 思路就是先找到最大的数&#xff0c;最大数的结果肯定是-1&#xff0c;然后倒着遍历数组&#xf…...

pyhon模块以及常用的第三方模块

import my_info as info print(info.name) info.show()from my_info import * print(name) show() pyhon中包的导入 import admin.my_admin as ad # 包名.模块名 admin是包名&#xff0c;my_admin是模块名print(ad.name) print(ad.info())from admin import my_admin as ad # …...

shell脚本—快速修改centos网络配置

shell-文本中自行修改想要的配置 #!/bin/bash# 网卡名称 eth"eth0"# IP 地址 ipaddr"192.168.1.100"# 子网掩码 netmask"255.255.255.0"# 网关 gateway"192.168.1.1"# 写入配置文件 echo "BOOTPROTOstatic" > /etc/sysc…...

线程池概念、线程池的不同创建方式、线程池的拒绝策略

文章目录 &#x1f490;线程池概念以及什么是工厂模式&#x1f490;标准库中的线程池&#x1f490;什么是工厂模式&#xff1f;&#x1f490;ThreadPoolExecutor&#x1f490;模拟实现线程池 &#x1f490;线程池概念以及什么是工厂模式 线程的诞生是因为&#xff0c;频繁的创…...

示例:WPF中如何绑定ContextMenu和Menu

一、目的&#xff1a;开发过程中&#xff0c;有些模块的右键ContextMenu菜单是需要动态显示的&#xff0c;既是根据不同条件显示不同的菜单&#xff0c;很多是通过代码去生成ContextMenu的MenuItem&#xff0c;本文介绍通过绑定的方式去加载ContextMenu&#xff0c;Menu菜单栏的…...

区块链小故事

大灰狼与小白兔 一天兔子妈妈出门了&#xff0c;在大门上安装了一个区块链的门把手&#xff0c;这个门把手只有兔子妈妈、小兔子、以及另一个客人都同意的时候&#xff0c;才会开门&#xff0c;有一天客人a的钥匙丢了&#xff0c;被大灰狼捡到了&#xff0c;大灰狼于是去开门&…...

Java | Leetcode Java题解之第167题两数之和II-输入有序数组

题目&#xff1a; 题解&#xff1a; class Solution {public int[] twoSum(int[] numbers, int target) {int low 0, high numbers.length - 1;while (low < high) {int sum numbers[low] numbers[high];if (sum target) {return new int[]{low 1, high 1};} else i…...

项目训练营第三天

项目训练营第三天 注册登录测试 前面我们编写了用户注册、登录的逻辑代码&#xff0c;每编写完一个功能模块之后&#xff0c;我们都要对该模块进行单元测试&#xff0c;来确保该功能模块的正确性。一般情况下使用快捷键Ctrl Shift Insert&#xff0c;鼠标左击类名可以自动生…...

计算机组成原理 | CPU子系统(1)基本概述

基本结构模型 运算与缓存部件 数据寄存部件 PSW不是很清楚 存储器是什么&#xff1f;属于那个结构里&#xff1f; 时序处理部件 cpu是大脑&#xff0c;控制器是神经元 ①通过硬件产生控制信号 ②通过软件产生控制信号 外频&#xff08;系统时钟信号&#xff09;&#xff0c;…...

无引擎游戏开发(2):最简游戏框架 | EasyX制作井字棋小游戏I

一、EasyX中的坐标系 不同于数理中的坐标系&#xff0c;EasyX中的y轴是竖直向下的 二、渲染缓冲区 之前的程序添加了这三个函数改善了绘图时闪烁的情况: 小球在"画布“上移动的过程就是我们在调用绘图函数&#xff0c;这个”画布“就是渲染缓冲区&#xff0c;先绘制的内…...

排书 IDA*

原题链接 题目描述 给定 n 本书&#xff0c;编号为 1∼n。 在初始状态下&#xff0c;书是任意排列的。在每一次操作中&#xff0c;可以抽取其中连续的一段&#xff0c;再把这段插入到其他某个位置。我们的目标状态是把书按照 1∼n 的顺序依次排列。求最少需要多少次操作。 输…...

playwright录制脚本原理

Paywright录制工具UI 在上一篇博客中介绍了如何从0构建一款具备录制UI测试的小工具。此篇博客将从源码层面上梳理playwright录制原理。当打开playwright vscode插件时&#xff0c;点击录制按钮&#xff0c;会开启一个新浏览器&#xff0c;如下图所示&#xff0c;在新开浏览器页…...

awk脚本监控

awk脚本监控 使用脚本监控内存&#xff0c;cpu和硬盘的根目录&#xff0c;超过80%提示用户&#xff0c;写成函数库的行&#xff0c;每天早上 的8.50分&#xff0c;执行一次脚本 现在脚本中写需要的内容 cpuu () {aa$(top -b -n 1 |awk NR3 {printf "%.F",$2$4})if …...

Python高压电容导电体和水文椭圆微分

&#x1f3af;要点 &#x1f3af;二维热传导二阶偏微分方程 | &#x1f3af;调和函数和几何图曲率 | &#x1f3af;解潮汐波动方程 | &#x1f3af;解静止基态旋转球体流体运动函数 | &#x1f3af;水文空间插值 | &#x1f3af;流体流动模拟求解器 | &#x1f3af;随机算法解…...

微信小程序 引入MiniProgram Design失败

这tm MiniProgramDesign 是我用过最垃圾的框架没有之一 我按照官网的指示安装居然能安装不成功,牛! 这里说明我是用js开发的 到以上步骤没有报错什么都没有,然后在引入组件的时候报错 Component is not found in path “./miniprogram _npm/vant/weapp/button/index” (using…...

Java 8 Date and Time API

Java 8引入了新的日期和时间API&#xff0c;位于java.time包下&#xff0c;旨在替代旧的java.util.Date和java.util.Calendar类。新API更为简洁&#xff0c;易于使用&#xff0c;并且与Joda-Time库的一些理念相吻合。以下是Java 8 Date and Time API中几个核心类的简要概述&…...

foobox-cn:让foobar2000从工具变身艺术品的终极美化方案

foobox-cn&#xff1a;让foobar2000从工具变身艺术品的终极美化方案 【免费下载链接】foobox-cn DUI 配置 for foobar2000 项目地址: https://gitcode.com/GitHub_Trending/fo/foobox-cn 你是否还在忍受foobar2000那过于朴素的默认界面&#xff1f;是否觉得功能强大的播…...

OpenClaw日志分析:Qwen3-32B每日自动汇总服务器异常事件

OpenClaw日志分析&#xff1a;Qwen3-32B每日自动汇总服务器异常事件 1. 为什么需要自动化日志分析 作为一名运维工程师&#xff0c;我每天早晨的第一项工作就是检查服务器日志。Nginx的错误日志、系统内核日志、应用服务的异常输出……这些文件分散在不同的目录&#xff0c;格…...

Qwen2-VL-2B-Instruct助力Java开发:智能代码注释与文档生成实战

Qwen2-VL-2B-Instruct助力Java开发&#xff1a;智能代码注释与文档生成实战 写Java代码最烦什么&#xff1f;对我来说&#xff0c;除了调试那些神出鬼没的Bug&#xff0c;就是写注释和文档了。明明代码逻辑自己一清二楚&#xff0c;但要把它转化成清晰、规范的文档&#xff0c…...

开源工具OptiScaler:突破显卡限制的跨平台上采样解决方案

开源工具OptiScaler&#xff1a;突破显卡限制的跨平台上采样解决方案 【免费下载链接】OptiScaler DLSS replacement for AMD/Intel/Nvidia cards with multiple upscalers (XeSS/FSR2/DLSS) 项目地址: https://gitcode.com/GitHub_Trending/op/OptiScaler OptiScaler是…...

【仅限核心开发者知晓】Polars 2.0清洗Pipeline的4层IR抽象:为何比Pandas快11.8倍?源码注释级解读

第一章&#xff1a;Polars 2.0清洗Pipeline的演进本质与性能跃迁全景Polars 2.0 将清洗 Pipeline 从“惰性执行显式优化提示”升级为“全图级自动重写零拷贝流式调度”&#xff0c;其本质是将数据清洗从过程式编排转向声明式语义图推理。核心突破在于 LazyFrame 的物理计划生成…...

在openKylin下安装配置GitLab遇到的问题及解决方案(v0.1.0)

作者&#xff1a;沈传越 明德融创工作室&#xff08;Minter Fusion Studio, MFS&#xff09; 出品 本文安装的GitLab-ce 15.10.0版。操作系统openKylin 2.0 SP2。 一、安装GitLab-ce依赖软件时报错 1. 错误描述 在执行sudo apt-get install curl openssh-server ca-certifi…...

OBS Studio架构深度解析:如何构建专业级直播系统的核心技术栈

OBS Studio架构深度解析&#xff1a;如何构建专业级直播系统的核心技术栈 【免费下载链接】obs-studio OBS Studio - 用于直播和屏幕录制的免费开源软件。 项目地址: https://gitcode.com/GitHub_Trending/ob/obs-studio OBS Studio作为开源直播录制软件的标杆&#xff…...

TwinCAT3 PLC安装避坑指南:从EtherCAT驱动到系统配置的完整流程

TwinCAT3 PLC实战安装指南&#xff1a;从零搭建工业控制系统的关键步骤 第一次接触TwinCAT3的工程师往往会被其强大的功能和复杂的配置流程所震撼。作为工业自动化领域的瑞士军刀&#xff0c;TwinCAT3将PLC、运动控制和实时通信集成在一个平台上&#xff0c;但这也意味着安装过…...

OpenClaw对话日志分析:GLM-4.7-Flash任务执行成功率提升

OpenClaw对话日志分析&#xff1a;GLM-4.7-Flash任务执行成功率提升 1. 为什么需要分析对话日志 上个月我把本地部署的OpenClaw智能体从Qwen切换到了GLM-4.7-Flash模型&#xff0c;本以为会获得更好的任务执行效果&#xff0c;结果却遇到了意想不到的问题。每天早上打开电脑&…...

基于Whisper-large-v3的语音搜索引擎开发

基于Whisper-large-v3的语音搜索引擎开发 你有没有遇到过这种情况&#xff1f;手头有几百个小时的会议录音、课程录像或者播客音频&#xff0c;想找其中某个人说过的一句话&#xff0c;或者某个特定的知识点&#xff0c;结果只能从头到尾听一遍&#xff0c;费时又费力。或者&a…...