sergiusz.kierat sergiusz.kierat - 2 months ago 10x
Scala Question

Scala: How to test methods that call System.exit()?

I have been developing a command-line tool which calls

(don't want to use exceptions instead of) on certain inputs.

I am familiar with Java: How to test methods that call System.exit()? and its the most elegant approach.

Unfortunately, it is not enough pure, due to I had to add the dependencies to system-rules, junit-interface

Is there any common pattern for dealing with
in specs2 which is more pure than my current approach which don't use specs2?

import org.junit.Rule;
import org.junit.Test;

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

public void emptyArgs() {
Converter.main(new String[]{});

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

Ven Ven

If you really wish to go with a method using System.exit(), the simplest way to test it was actually called is to replace your SecurityManager with one that'll throw an ExitException (subclassing SecurityException) when System.exit() is called:

class SystemExitSpec


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 = {
    throw ExitException(status)

abstract class SystemExitSpec extends Specification with BeforeAfterAll {


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

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

test ConverterSpec

import org.specs2.execute.Failure


class ConverterSpec extends SystemExitSpec {

"ConverterSpec" should {

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