如何编写测试检查字符串解析错误模式并捕获指定失败消息
解决scopt解析错误消息捕获问题
问题出在你的parseArgs方法里——当解析失败时,你用sys.error("Could not parse arguments")抛出了一个固定消息的异常,完全丢掉了scopt生成的自定义验证失败消息。要捕获到目标错误文本,你有两种可行的修改方向:
方案1:修改parseArgs传递原始错误消息
调整你的TestConfig.parseArgs方法,让它把scopt收集到的错误消息包含在抛出的异常中:
object TestConfig { private val parser = new scopt.OptionParser[TestConfig]("Test") { // 保留原有的配置和验证逻辑 opt[String]('r', "stringArrayWithNumbers") .validate { mrs => if (mrs.matches("""\d+(?:\s*,\s*\d+)*""")) success else failure("String should not be in pattern number with comma.") } // ...其他配置 } def parseArgs(args: Array[String]): TestConfig = parser.parse(args, TestConfig()) match { case Some(config) => config case None => // 提取scopt生成的所有错误消息 val errorDetails = parser.failureMessages.mkString("\n") sys.error(s"Could not parse arguments: $errorDetails") } }
然后修改测试代码,验证异常消息包含你的目标文本:
"TestConfig" should "return failure of incorrect String pattern" in { val cmdLine = "--numbers 1,2,3,4," val args = cmdLine.split("\\s+") // 用\\s+避免拆分出空字符串 val thrown = the[RuntimeException] thrownBy TestConfig.parseArgs(args) thrown.getMessage should include("String should not be in pattern number with comma.") }
方案2:直接测试scopt Parser的行为(更推荐)
如果你不想修改生产代码,也可以绕过parseArgs,直接调用parser的parse方法,然后检查它的失败消息:
"TestConfig" should "return failure of incorrect String pattern" in { val cmdLine = "--numbers 1,2,3,4," val args = cmdLine.split("\\s+") val parseResult = TestConfig.parser.parse(args, TestConfig()) // 首先验证解析确实失败了 parseResult shouldBe None // 然后检查是否包含目标错误消息 TestConfig.parser.failureMessages should contain("String should not be in pattern number with comma.") }
为什么这个方法更优?
- 不需要改动生产代码,测试更纯粹
- 直接验证scopt的核心行为,避免被包装层的异常处理干扰
- 可以同时验证多个错误消息(如果有多个验证失败的情况)
额外小提示
你原来的测试里用了stripMargin和replace("\r\n", ""),其实可以简化成直接写无多余空格的命令行字符串,然后用split("\\s+")拆分参数,这样能避免生成空的参数项,减少解析时的额外问题。
内容的提问来源于stack exchange,提问作者Vadim
相关产品推荐
相关产品推荐

