如何在uTest中测试Scala ProcessBuilder并Mock HTTP请求验证404场景?
在uTest中Mock HTTP调用验证Scala代码行为
你的代码直接硬编码了HTTP下载逻辑(Scala IO的URL#>!操作),这种紧耦合的写法无法直接Mock。要实现测试,第一步需要重构代码,抽象出下载依赖,这样才能在测试中替换为Mock实现。
1. 重构核心代码,抽象下载逻辑
先定义一个trait封装下载行为,让业务代码依赖这个抽象,而非直接依赖Scala IO的URL操作:
import java.io.File import java.net.URL import scala.util.Try import java.nio.file.Paths // 抽象下载器接口 trait HttpDownloader { def download(url: URL, destination: File): Try[Unit] } // 真实环境的下载实现 class RealHttpDownloader extends HttpDownloader { override def download(url: URL, destination: File): Try[Unit] = { Try { (url #> destination).!! // 原有的下载逻辑 } } } // 你的业务逻辑,现在依赖抽象的HttpDownloader def processResource(url: URL, downloader: HttpDownloader): Try[Resource] = { val tempDestination = Paths.get("/tmp/fred").toFile for { _ <- downloader.download(url, tempDestination) _ = streams.debug(s"Downloaded $url to $tempDestination with size equal to ${tempDestination.length} bytes") resource <- doStuff(tempDestination) } yield resource }
2. 实现Mock下载器模拟404错误
在测试中,我们需要一个Mock的HttpDownloader,调用时直接抛出模拟404的异常:
// Mock下载器,模拟HTTP 404错误 class Mock404Downloader extends HttpDownloader { override def download(url: URL, destination: File): Try[Unit] = { Try { // 抛出模拟的404异常 throw new java.io.IOException("HTTP 404 Not Found") } } }
3. 编写uTest测试用例
现在可以在uTest中使用Mock下载器,验证下载失败时业务代码的行为:
import utest._ object ResourceProcessingTests extends TestSuite { val tests = Tests { test("HTTP返回404时,流程应终止且不执行后续逻辑") { val testUrl = new URL("https://example.com") val mockDownloader = new Mock404Downloader() // 调用业务逻辑 val result = processResource(testUrl, mockDownloader) // 验证结果为Failure且包含预期异常 assert(result.isFailure) assert(result.failed.get.getMessage.contains("HTTP 404 Not Found")) // 可选:若doStuff也做了抽象,可额外验证它未被调用 } } }
补充说明
- 如果
doStuff也存在外部依赖,同样需要抽象,才能在测试中验证它的调用状态(可结合Mockito等第三方Mock库)。 - 若需要验证
streams.debug的输出,可通过替换日志实现来捕获输出内容。
内容的提问来源于stack exchange,提问作者brisssou
相关产品推荐
相关产品推荐

