在 Always Null 中可调用

Callable in Always Null

我有以下 Java 代码用于重试某个操作

package helpers;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public final class Retry {

    public static <V> V execute(Callable<V> action, Duration retryInterval, int retryCount)
        throws AggregateException {

        List<Throwable> exceptions = new ArrayList<>();
        for (int retry = 0; retry < retryCount; ++retry) {

            try {
                if (retry > 0)
                    Thread.sleep(retryInterval.toMillis());
                return action.call();

            } catch (Throwable t) {
                exceptions.add(t);
            }
        }
        throw new AggregateException(exceptions);
    }

    public static <V> Future executeAsync(Callable<V> action, Duration retryInterval, int retryCount)
        throws AggregateException {

        FutureTask<V> task = new FutureTask<>(action);
        ExecutorService executor = Executors.newSingleThreadExecutor();
        return executor.submit(task);
    }
}

我正在尝试通过

测试同步代码的功能
package helpers;

import org.junit.Before;
import org.junit.Test;

import java.text.MessageFormat;
import java.time.Duration;
import java.util.concurrent.Callable;

import static org.junit.Assert.assertEquals;

public class RetryTest {

    private Integer counter = 0;
    private Callable<Integer> calculator;

    @Before
    public void init() {
        calculator = () -> {
            for (int i = 0; i < 3; ++i) {
                counter++;
                System.out.println(MessageFormat.format(
                    "Counter = {0}", Integer.toString(counter)));
            }
            if (counter < 6)
                throw new Exception();
            return counter;
        };
    }

    @Test
    public void execute() throws AggregateException {

        Integer result = Retry.execute(calculator, Duration.ofSeconds(1), 3);
        assertEquals(9, java.util.Optional.ofNullable(result));
    }
}

但是 calculatorRetry.execute(calculator, Duration.ofSeconds(1), 3); 中为空,为什么我在这里做错了什么?

我正在使用 Junit 4.12。


我也试过完整的语法

@Before
    public void init() {
        calculator = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                for (int i = 0; i < 3; ++i) {
                    counter++;
                    System.out.println(MessageFormat.format(
                        "Counter = {0}", Integer.toString(counter)));
                }
                if (counter < 6)
                    throw new Exception();
                return counter;
            }
        };
    }

仍为空。

好吧,我使用 JUnit 3 进行了测试,但从未调用过 @Before。然后我用 JUnit 4 进行了测试并且正在调用 @Before ,尝试查看您的 JUnit 版本。

你能用这个测试代码检查一下吗?

public class RetryTest {


    @Test
    public void execute() throws AggregateException {

        Integer result = Retry.execute(getCallableCalculater(), Duration.ofSeconds(1), 3);
        assertEquals(9, java.util.Optional.ofNullable(result));
    }

    private Callable<Integer> getCallableCalculater() {

        final Integer[] counter = {0};
        return () -> {
            for (int i = 0; i < 3; ++i) {
                counter[0]++;
                System.out.println(MessageFormat.format(
                        "Counter = {0}", Integer.toString(counter[0])));
            }
            if (counter[0] < 6)
                throw new Exception();
            return counter[0];
        };
    }
}