1 // Copyright 2020 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base.test; 6 7 import org.junit.rules.TestRule; 8 import org.junit.runner.Description; 9 import org.junit.runners.model.Statement; 10 11 import org.chromium.base.Log; 12 import org.chromium.build.annotations.CheckDiscard; 13 14 /** 15 * Attempts to provide additional information for Mockito errors that are hard to diagnose, 16 * b/147584922 in particular. 17 */ 18 class MockitoErrorHandler implements TestRule { 19 private static final String TAG = "MockitoErrorHandler"; 20 21 private static final String MOCKITO_ERROR = 22 "Note: Proguard optimization is enabled and may cause exceptions when Mocking Derived" 23 + " classes, or classes that implement interfaces whose methods are not kept. You" 24 + " may need to add org.chromium.build.annotations.MockedInTests to such classes."; 25 26 @CheckDiscard("") removedMethodUnderRelease()27 private void removedMethodUnderRelease() {} 28 29 @Override apply(Statement base, Description description)30 public Statement apply(Statement base, Description description) { 31 return new Statement() { 32 @Override 33 public void evaluate() throws Throwable { 34 try { 35 base.evaluate(); 36 } catch (Throwable e) { 37 if ((e instanceof AbstractMethodError) 38 // UnfinishedStubbingException isn't on our build path. 39 || e.getClass().getSimpleName().equals("UnfinishedStubbingException")) { 40 try { 41 // Detect if code is being optimized. 42 getClass().getDeclaredMethod("removedMethodUnderRelease"); 43 } catch (NoSuchMethodException ignored) { 44 Log.e(TAG, MOCKITO_ERROR); 45 } 46 } 47 throw e; 48 } 49 } 50 }; 51 } 52 } 53