JMockit:如何调用MockUp的自定义方法

时间:2014-05-06 10:38:18

标签: java jmockit

我的应用使用FastScanner(基于BufferedReader)来阅读输入(查看我的问题的代码部分)。

如果我想在测试中替换输入,我应该模拟FastScanner查看我的问题的代码部分)。

问题: For each input I should make separate mockup.如果我可以在单个Mock Up中切换输入,那就太大了。

问题: How to add custom methods to JMockit MockUps and than call them?查看switchInput模型的FastScanner方法

代码:[此部分是可选的,仅供您更好理解]

FastScanner

protected static class FastScanner {
    BufferedReader br;
    StringTokenizer st;

    FastScanner(InputStream f) {
        br = new BufferedReader(new InputStreamReader(f));
    }

    String next() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(br.readLine());
        }
        return st.nextToken();
    }

    int nextInt() throws IOException {
        return Integer.parseInt(next());
    }
} 

FastScanner MockUp:

new MockUp<FastScanner>() {

        private int[] input1 = new int[] {17, 2, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1};
        private int[] input2 = new int[] {5, 2, 2, 3, 3, 3, 3, 3};
        private int[] input3 = new int[] {8, 2, 5, 1, 3, 1, 1, 1, 1, 3, 1};
        private byte toggler = 1;
        private byte pointer = 0;

        //HERE THE QUESTION: HOW CAN I CALL THIS METHOD
        public void switchInput() { 
            toggler++;
            pointer = 0;
        }

        @SuppressWarnings("unused")
        int nextInt() throws IOException {
            int[] input = null;
            switch (toggler) {
                case 1: input = input1; break;
                case 2: input = input2; break;
                case 3: input = input3; break;
            }
            return input[pointer++];
        }
    };

2 个答案:

答案 0 :(得分:1)

您不能同时拥有相同MockUp子类的多个实例(每个此类模型在实例化时会简单地覆盖前一个实例)。相反,在Invocation方法中添加@Mock参数,然后使用它提供的信息来区分多个数据集。例如:

@Test
public void testClientWithVariedDataFromFastScanners()
{
    new MockUp<FastScanner>() {
        // some data structure for test data

        @Mock
        int nextInt(Invocation inv) {
            int idx = inv.getInvocationIndex();
            FastScanner fs = inv.getInvokedInstance();

            // Find the next value by using idx or fs as a lookup index
            // into the data structures:
            int i = ...

            return i;
        }
    };

    client.doSomethingUsingFastScanners();
}

此外,如果要在模型子类上调用任何方法(包括static方法),只需将其设为命名的类而不是匿名类。

答案 1 :(得分:0)

也许它比@ Rogerio的解决方案更糟糕,但我们可以使用带有静态字段的外部类。我的意思是:

    new MockUp<PrisonTransfer.FastScanner>() {

        private int[] input1 = new int[] {17, 2, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1};
        private int[] input2 = new int[] {5, 2, 2, 3, 3, 3, 3, 3};
        private int[] input3 = new int[] {8, 2, 5, 1, 3, 1, 1, 1, 1, 3, 1};
        private int[] input4 = new int[] {4, 3, 3, 2, 3, 1, 1};
        private int[] input5 = new int[] {1, 1, 1, 2};
        private int[] input6 = new int[] {11, 4, 2, 2, 2, 0, 7, 3, 2, 2, 4, 9, 1, 4};

        @SuppressWarnings("unused")
        @Mock
        int nextInt() throws IOException {
            int[] input = null;
            switch (InputCounter.inputNumber) { //THE WHOLE POINT HERE!
                case 1: input = input1; break;
                case 2: input = input2; break;
                case 3: input = input3; break;
                case 4: input = input4; break;
                case 5: input = input5; break;
                case 6: input = input6; break;
            }
            return input[InputCounter.pointer++];
        }
    };

    private static class InputCounter {
        public static byte inputNumber = 1;
        public static byte pointer = 0;

        public void switchInput(int number) {
            this.inputNumber = i;
            this.pointer = 0;
        }
    }