Scala:如何测试调用System.exit()的方法?

标签 scala unit-testing sbt specs2 testability

我一直在开发一个命令行工具,该工具在某些输入上调用System.exit()(不想使用异常代替)。

我熟悉Java: How to test methods that call System.exit()?及其最优雅的approach

不幸的是,由于我不得不将依赖项添加到system-rulesjunit-interface中,它还不够纯净

specs2 中是否有任何常见的处理System.exit的模式,这比我目前不使用 specs2 的方法更为纯净?

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ExpectedSystemExit;

public class ConverterTest {
    @Rule
    public final ExpectedSystemExit exit = ExpectedSystemExit.none();

    @Test
    public void emptyArgs() {
        exit.expectSystemExit();
        Converter.main(new String[]{});
    }

    @Test
    public void missingOutArgument() {
        exit.expectSystemExitWithStatus(1);
        Converter.main(new String[]{"--in", "src/test/resources/078.xml.gz"});
    }
}

最佳答案

如果您真的希望使用一种使用System.exit()的方法,则测试该方法的最简单方法实际上是将您的SecurityManager替换为一种在调用ExitException时会抛出SecurityException(子类化为System.exit())的方法:

SystemExitSpec

import java.security.Permission

import org.specs2.mutable.Specification
import org.specs2.specification.BeforeAfterAll

sealed case class ExitException(status: Int) extends SecurityException("System.exit() is not allowed") {
}

sealed class NoExitSecurityManager extends SecurityManager {
  override def checkPermission(perm: Permission): Unit = {}

  override def checkPermission(perm: Permission, context: Object): Unit = {}

  override def checkExit(status: Int): Unit = {
    super.checkExit(status)
    throw ExitException(status)
  }
}


abstract class SystemExitSpec extends Specification with BeforeAfterAll {

  sequential

  override def beforeAll(): Unit = System.setSecurityManager(new NoExitSecurityManager())

  override def afterAll(): Unit = System.setSecurityManager(null)
}

测试 ConverterSpec
import org.specs2.execute.Failure

import scala.io.Source

class ConverterSpec extends SystemExitSpec {

"ConverterSpec" should {

    "empty args" >> {
      try {
        Converter.main(Array[String]())
        Failure("shouldn't read this code")
      } catch {
        case e: ExitException =>
          e.status must_== 1
      }
      1 must_== 1
    }
}

关于Scala:如何测试调用System.exit()的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39073930/

相关文章:

scala - Predef.readLine 行为

scala - 为什么以下代码会泄漏 Slick 数据库集合?

Scala - 如果存在,则删除文件,Scala 方式

java - Mockito,doNothing() When() 的用法

java - Play Framework 2.4.0 - 如何将外部 java 项目依赖项添加到 play-java 应用程序项目

Scala 导入问题 - 错误 : not found: value

ios - 如何在不使用任何模拟库的情况下模拟 iOS Swift 中的系统库?

unit-testing - FluentAssertions ShouldBeEquivalentTo() 与 Should().BeEquivalentTo()

scala - SBT 进入错误目录

java - 如何在子项目之间共享 application.conf 文件?