### Question:
CircuitBreakerWrapperHelper { @SuppressWarnings("unchecked") public static <T> T wrapWithCircuitBreaker(T target, CircuitBreaker circuitBreaker) { ProxyFactory proxyFactory = new ProxyFactory(); Class<?> targetClass = target.getClass(); if (Modifier.isFinal(targetClass.getModifiers())) { proxyFactory.setInterfaces(targetClass.getInterfaces()); } else { proxyFactory.setSuperclass(targetClass); } proxyFactory.setFilter(m -> !IGNORED_METHODS.contains(m.getName())); Class proxyClass = proxyFactory.createClass(); Map<String, Method> methods = new HashMap<>(); for (Method method : targetClass.getMethods()) { methods.put(method.getName(), method); } Proxy proxy = (Proxy) OBJENESIS.newInstance(proxyClass); proxy.setHandler( (self, m, proceed, args) -> circuitBreaker.executeCheckedSupplier( () -> { try { return methods.get(m.getName()).invoke(target, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } })); return (T) proxy; } private  CircuitBreakerWrapperHelper(); @SuppressWarnings("unchecked") static T wrapWithCircuitBreaker(T target, CircuitBreaker circuitBreaker);  }### Answer:
@Test public void shouldWrapClassWithDefaultConstructor() { CircuitBreaker circuitBreaker = CircuitBreakerRegistry.ofDefaults().circuitBreaker("wrap"); Simple target = new SimpleImpl(); Simple wrapped = CircuitBreakerWrapperHelper.wrapWithCircuitBreaker(target, circuitBreaker); assertThat(wrapped.check()).isEqualTo(42); assertThat(circuitBreaker.getMetrics().getNumberOfSuccessfulCalls()).isEqualTo(1); }
@Test public void shouldWrapClassWithoutDefaultConstructor() { CircuitBreaker circuitBreaker = CircuitBreakerRegistry.ofDefaults().circuitBreaker("wrap"); Complex target = new Complex(42); Complex wrapped = CircuitBreakerWrapperHelper.wrapWithCircuitBreaker(target, circuitBreaker); assertThat(wrapped.check()).isEqualTo(42); assertThat(circuitBreaker.getMetrics().getNumberOfSuccessfulCalls()).isEqualTo(1); }
@Test public void shouldWrapClassWithoutDefaultConstructorAndWithoutInterface() { CircuitBreaker circuitBreaker = CircuitBreakerRegistry.ofDefaults().circuitBreaker("wrap"); NoDefaultConstructor target = new NoDefaultConstructor(42); NoDefaultConstructor wrapped = CircuitBreakerWrapperHelper.wrapWithCircuitBreaker(target, circuitBreaker); assertThat(wrapped.check()).isEqualTo(42); assertThat(circuitBreaker.getMetrics().getNumberOfSuccessfulCalls()).isEqualTo(1); }
@Test public void shouldWrapClassWithoutDefaultConstructorViaInterface() { CircuitBreaker circuitBreaker = CircuitBreakerRegistry.ofDefaults().circuitBreaker("wrap"); Simple target = new ComplexImpl(42); Simple wrapped = CircuitBreakerWrapperHelper.wrapWithCircuitBreaker(target, circuitBreaker); assertThat(wrapped.check()).isEqualTo(42); assertThat(circuitBreaker.getMetrics().getNumberOfSuccessfulCalls()).isEqualTo(1); }
@Test public void shouldWrapDynamicProxy() { CircuitBreaker circuitBreaker = CircuitBreakerRegistry.ofDefaults().circuitBreaker("wrap"); Simple target = (Simple) Proxy.newProxyInstance( getClass().getClassLoader(), new Class[] {Simple.class}, (proxy, method, methodArgs) -> { if (method.getName().equals("check")) { return 42; } else { throw new UnsupportedOperationException( "Unsupported method: " + method.getName()); } }); Simple wrapped = CircuitBreakerWrapperHelper.wrapWithCircuitBreaker(target, circuitBreaker); assertThat(wrapped.check()).isEqualTo(42); assertThat(circuitBreaker.getMetrics().getNumberOfSuccessfulCalls()).isEqualTo(1); }