Scala: Как проверить методы, которые вызывают System.exit()?
Я разрабатывал инструмент командной строки, который вызывает System.exit()
(не хочу использовать исключения вместо) на определенных входах.
Я знаком с Java: как тестировать методы, вызывающие System.exit()? и это самый элегантный подход.
К сожалению, это недостаточно чисто, из-за того, что мне пришлось добавить зависимости к системным правилам, junit-interface
Есть ли какая-то общая картина для борьбы с System.exit
в specs2, который является более чистым, чем мой текущий подход, который не использует 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"});
}
}
2 ответа
Если вы действительно хотите использовать метод, использующий 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
}
}
Первый вариант: использовать какое-то исключение вместо System.exit
,
Второй вариант: вызвать приложение в отдельном потоке и проверить коды возврата.
Третий вариант: макет System.exit
, Есть много возможностей сделать это, упомянутая очень хорошая.
Тем не менее, нет specs2
-конкретный шаблон для работы с System.exit
, Лично я бы предложил первый или второй варианты.