我一直在开发一个命令行工具,在某些输入上调用System.exit()
(不想使用异常而不是)。
我熟悉Java: How to test methods that call System.exit()?及其最优雅的approach。
不幸的是,由于我必须将依赖项添加到system-rules,junit-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"});
}
}
答案 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
特定模式。我个人建议第一或第二选择。