4

In JUnit, using a TestWatcher and Overriding the failed() function, is it possible to remove the thrown exception and instead make my own assertion?

The use case is : with functional tests on Android, when a test makes the app crashes, I would like to replace the NoSuchElementException with an AssertionError ("app crashed").

I have no problem to make the custom assertion (when I detect a crash in finished() method) , but how to remove the thrown exception ?

Because in my report it creates for one test the exception and the assertion, so there are more failures than test in failure, which is logic but annoying.

I was wondering if there were a way to customize the Throwable object to remove the specific NoSuchElementException, manipulating the stacktrace.

I didn't manage to do it. (And necessarily I don't want to perform it using a try/catch in every tests ...).

Fanch
  • 3,274
  • 3
  • 20
  • 51

2 Answers2

3

You could override TestWatcher.apply and add a special catch for NoSuchElementException:

public class MyTestWatcher extends TestWatcher {
    public Statement apply(final Statement base, final Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                List<Throwable> errors = new ArrayList<Throwable>();

                startingQuietly(description, errors);
                try {
                    base.evaluate();
                    succeededQuietly(description, errors);
                }
                catch (NoSuchElementException e) {
                    // ignore this
                }
                catch (AssumptionViolatedException  e) {
                    errors.add(e);
                    skippedQuietly(e, description, errors);
                }
                catch (Throwable e) {
                    errors.add(e);
                    failedQuietly(e, description, errors);
                }
                finally {
                    finishedQuietly(description, errors);
                }

                MultipleFailureException.assertEmpty(errors);
            }
        };
    }
CKuck
  • 702
  • 5
  • 18
1

You can do it by bypassing. An example code is given below. Hope it will help you.

try {
// Write your code which throws exception
----
----
----

} catch (NoSuchElementException ex) {
    ex.printStackTrace();
    if (ex instanceof NoSuchElementException) { // bypass
                                                // NoSuchElementException
        // You can again call the method and make a counter for deadlock
        // situation or implement your own code according to your
        // situation
        AssertionError ("app crashed");
        if (retry) {
            ---
            ---
            return previousMethod(arg1, arg2,...);
        } else {
            throw ex;
        }
    }
} catch (final Exception e) {
    e.printStackTrace();
    throw e;
}

I have solved this type of issue previously. My another answer has details. You can go through my another answer: android.security.KeyStoreException: Invalid key blob

Community
  • 1
  • 1
SkyWalker
  • 28,384
  • 14
  • 74
  • 132