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

时间:2016-08-22 07:48:03

标签: 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 的方法更纯粹? / p>

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"});
    }
}

2 个答案:

答案 0 :(得分:7)

如果您真的希望使用System.exit()的方法,最简单的测试方法实际上就是将SecurityManager替换为ExitException以及SecurityException调用System.exit()时(子类化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) } ):

SystemExitSpec

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
    }
}

测试 ConverterSpec

UNION ALL

答案 1 :(得分:1)

第一个选项:使用一些例外而不是Matrix dimensions must agree

第二个选项:在单独的线程中调用应用程序并检查返回代码。

第三个选项:模拟CREATE TABLE buildings (   building_no int(11) NOT NULL AUTO_INCREMENT,   building_name varchar(255) NOT NULL,   address varchar(355) NOT NULL,   PRIMARY KEY (building_no) ) ENGINE=InnoDB; CREATE TABLE rooms (   room_no int(11) NOT NULL AUTO_INCREMENT,   room_name varchar(255) NOT NULL,   building_no int(11) NOT NULL,   PRIMARY KEY (room_no),   KEY building_no (building_no),   CONSTRAINT rooms_ibfk_1   FOREIGN KEY (building_no)   REFERENCES buildings (building_no)   ON DELETE CASCADE ) ENGINE=InnoDB 。有很多可能做到这一点,提到一个很好。

但是,System.exit无法使用System.exit特定模式。我个人建议第一或第二选择。