groovy:用 JUint 5 编写单元测试代码

参阅上一篇:groovy:XmlParser 读 Freeplane.mm文件,生成测试案例.csv文件

这是基于 Groovy 4.0 适配 JUnit 5 的测试代码,充分利用 Groovy 4.0 的新特性(如文本块、简化的 lambda 表达式等)对原测试案例进行优化:

下载 commons-io-2.15.0.jar 放在 D:\groovy-4.0.6\lib\

测试依赖(build.gradle

Groovy 4.0 需搭配兼容的依赖版本,build.gradle 配置如下:

plugins {
    id 'groovy'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.codehaus.groovy:groovy:4.0.18'  // Groovy 4.0 版本
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.0'  // JUnit 5 最新兼容版本
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.0'
    testImplementation 'org.apache.commons:commons-io:2.15.1'  // 适配 Groovy 4.0 的 IO 工具
}

test {
    useJUnitPlatform()
    testLogging {
        events 'PASSED', 'SKIPPED', 'FAILED'
    }
}

测试案例代码(XmlParserTest.groovy

import groovy.xml.XmlParser
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.*
import java.io.File
import org.apache.commons.io.FileUtils

class XmlParserTest {

    // 测试无输入参数时的提示信息(利用 Groovy 4.0 文本块简化字符串定义)
    @Test
    void testNoInputArgument() {
        def output = new ByteArrayOutputStream()
        System.out = new PrintStream(output)
        
        Example.main([] as String[])  // 简化空数组定义
        
        System.out = System.out  // 恢复标准输出
        
        // 使用文本块(Text Blocks)定义预期输出,增强可读性
        def expected = """ usage: groovy test_xmlparser file1.mm ;
"""
        assertEquals(expected, output.toString())
    }

    // 测试多层节点解析(Groovy 4.0 简化 lambda 表达式语法)
    @Test
    void testParseMultiLevelNodes() {
        // 创建临时文件,用文本块定义 XML 内容(支持换行和缩进)
        def tempFile = File.createTempFile("test", ".mm").tap {
            text = """
                <map>
                    <node @TEXT="Level 1">
                        <node @TEXT="Level 2-1">
                            <node @TEXT="Level 3-1"/>
                        </node>
                        <node @TEXT="Level 2-2">
                            <node @TEXT="Level 3-2">
                                <node @TEXT="Level 4-1"/>
                            </node>
                        </node>
                    </node>
                    <node @TEXT="Level 1-2"/>
                </map>
            """.stripIndent()  // Groovy 4.0 保留 stripIndent() 增强文本块格式化
        }

        def output = new ByteArrayOutputStream()
        System.out = new PrintStream(output)
        
        Example.main([tempFile.absolutePath] as String[])
        
        System.out = System.out
        
        // 文本块定义预期输出,直观对比层级结构
        def expectedOutput = """
Level 1
  Level 2-1
    Level 3-1
  Level 2-2
    Level 3-2
      Level 4-1
Level 1-2
""".stripIndent()
        assertEquals(expectedOutput, output.toString())
        
        tempFile.deleteOnExit()
    }

    // 测试空节点处理(Groovy 4.0 增强的空安全和属性访问)
    @Test
    void testParseNodesWithoutTextAttribute() {
        def tempFile = File.createTempFile("empty", ".mm").tap {
            text = """
                <map>
                    <node/>  <!-- 无 @TEXT 属性 -->
                    <node @TEXT=""/>  <!-- 空值 @TEXT -->
                    <node @TEXT="Valid Text"/>
                </map>
            """.stripIndent()
        }

        def output = new ByteArrayOutputStream()
        System.out = new PrintStream(output)
        
        Example.main([tempFile.absolutePath] as String[])
        
        System.out = System.out
        
        def expectedOutput = """

Valid Text
""".stripIndent()
        assertEquals(expectedOutput, output.toString())
        
        tempFile.deleteOnExit()
    }

    // 测试解析不存在的文件(Groovy 4.0 简化异常断言语法)
    @Test
    void testParseNonExistentFile() {
        def nonExistentFile = "nonexistent_${System.currentTimeMillis()}.mm"  // 确保文件不存在
        
        // Groovy 4.0 支持更简洁的闭包语法(省略 it 参数)
        assertThrows(FileNotFoundException) {
            Example.main([nonExistentFile] as String[])
        }
    }

    // 测试无效 XML 格式(验证解析异常)
    @Test
    void testParseInvalidXml() {
        def tempFile = File.createTempFile("invalid", ".mm").tap {
            text = """<map><node @TEXT='Invalid'><!-- 缺少闭合标签 -->"""  // 故意构造错误 XML
        }

        // 断言 XmlParser 解析错误时的异常(Groovy 4.0 兼容新异常类型)
        assertThrows(groovy.xml.XmlSyntaxException) {  // Groovy 4.0 中异常类名调整为 XmlSyntaxException
            Example.main([tempFile.absolutePath] as String[])
        }
        
        tempFile.deleteOnExit()
    }
}

// 待测试的 Example 类(适配 Groovy 4.0 语法)
class Example {
    static void main(String[] args) {
        if (args.size() < 1) {
            println " usage: groovy test_xmlparser file1.mm ;"
            return
        }
        def file1 = args[0]
        def parser = new XmlParser()
        def doc = parser.parse(file1)
        // Groovy 4.0 支持更简洁的链式调用和闭包语法
        doc.node.each { level1 ->
            println(level1['@TEXT'])  // 简化字符串拼接,直接打印属性值
            level1.node.each { level2 ->
                println("  ${level2['@TEXT']}")
                level2.node.each { level3 ->
                    println("    ${level3['@TEXT']}")
                    level3.node.each { level4 ->
                        println("      ${level4['@TEXT']}")
                        level4.node.each { level5 ->
                            println("        ${level5['@TEXT']}")
                        }
                    }
                }
            }
        }
    }
}

Groovy 4.0 特性说明

  1. 文本块(Text Blocks):用 """ 定义多行字符串,配合 stripIndent() 自动处理缩进,比传统字符串拼接更清晰(如测试预期输出和 XML 内容定义)。

  2. 简化的闭包语法:在 assertThrows 等方法中,可省略冗余的 it 参数,闭包逻辑更简洁。

  3. 增强的 tap 方法:用于链式初始化临时文件,简化文件创建和内容设置的代码(tempFile = File.createTempFile(...).tap { ... })。

  4. 异常类调整:Groovy 4.0 中 XML 解析错误的异常类从 XmlParser$ParseException 统一为 XmlSyntaxException,测试案例中已适配。

  5. 空安全与类型推断优化:Groovy 4.0 对空值处理和类型推断的增强,使代码更健壮(如参数校验和属性访问)。

以上代码可直接在 Groovy 4.0 环境中运行,通过 JUnit 5 验证原 XML 解析程序的各种场景,同时利用新版本特性提升了代码的可读性和简洁性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值